Monday, March 17, 2008

Publishing Web Application with MsBuild



Visual Studio 2005 has features that can used to publish a website in a production server or a staging server.When you compile files using the Publish Web Site utility the source code is removed. The marked up code in the .aspx files can also be removed optionally. After compilation the .aspx pages point to the compiled versions. With this feature the source code of your pages are safe. Accessing your code by others is difficult. This is one of the features that are more useful for those who want their code to be safe.

Question is how to automate it?

1. Add target to .csproj file
Ensure your web application project contains :

2. Call hidden task _CopyWebApplication
Call task from msbuild:


3. Resolve references to other projects
Unfortunatelly task _CopyWebApplicaiton does not copy output from referenced project so you have to do it manually by calling ResolveReferences task



Update: Publishing Websites with cascade dependency (2009.02.03)

It's quite common that you have project structure like on image below. Web site on top of Business Logic Layer, which is on top of Data Access Layer.

Unfortunately, solution posted above does not solve second degree references (references of references) and therefore. When project is built with code above only first degree are propery copied to output directory.


In order to configure all degree references to be copied you have to specify both
  • WebProjectOutputDir - where website will be published
  • OutDir - where all assemblies should be placed (bin folder>

In MsBuild script you can use snippet as below:

<MSBuild Projects="WebApplication\WebApplication.csproj"

Properties="Configuration=Release;WebProjectOutputDir=..\build\Release\Web\;OutDir= ..\builda\Release\Web\bin\"

Targets="ResolveReferences;_CopyWebApplication" />


Thanks to Maciej Grzyb for solution http://maciek79.secondbrain.com

8 comments:

dawood said...

Hi..

I am new to cruisecontrol and trying to integrate 'publish' for my web application.

My issue is that my website does not have 'csproj' file and hence i could not follow the procedure as described by you.
But, I could publish my website from VS2008 by rightclick on project and selecting 'publish website' option.

How can I achieve the same in 'msbuild' without 'csproj' file?
Is it possible to add 'csproj' file now to my website?

Kindly update

Mirosław Jedynak said...

There are (main) 2 types of asp.net application

-Web Sites (ASP.Net Web Site) - does not have csproj files, and files with code are placed under app_code directory, and then compiled when first request is made

-Web Applications (Asp.Net Web Application) - they have csproj and compiled source are placed in dll in 'bin' folder.

There was option to convert web site to web application from visual studio 2005, but now (vs 2008) you have to use techniques like: http://geekswithblogs.net/Mohamed/archive/2008/08/03/converting-vs-2008-website-to-web-application.aspx

Mirosław Jedynak said...
This comment has been removed by the author.
Mirosław Jedynak said...

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="PrecompileWeb">
<AspNetCompiler
VirtualPath="/MyWebSite"
PhysicalPath="c:\inetpub\wwwroot\MyWebSite\"
TargetPath="c:\precompiledweb\MyWebSite\"
Force="true"
Debug="true"
/>
</Target>
</Project>

Details: http://msdn.microsoft.com/en-us/library/ms164291.aspx

Unknown said...

We need the ability to Publish to a https address. However, the MSBuild command returns this error:

MSB4023: Cannot evaluate the item metadata "%(FullPath)". The item meta-data "%(FullPath)" cannot be applied to the path. The given path's format is not supported.

Is there any way to publish directly to a web connection?...we're also going to have to enter a username/password...we need a way to script that, but I have not found one thus far.

Unknown said...

Hi..

I am developing a web application where users will design an application, which i want to compile, and publish and host in IIS, programatically.

Could you tell me how can i do this.

Thanks in advance.

Mirosław Jedynak said...

The easiest approach would be to:
1) Dynamically create msbuild file from code
2) run msbuild.exe against created file

You can use Process.Start("c:\...\msbuild.exe","msbuild_file and/or other arguments"), Check http://msdn.microsoft.com/en-us/library/h6ak8zt5.aspx

Anonymous said...

The alternative to launching MSbuild process is to use Microsoft.Build.Execution.BuildManager.DefaultBuildManager.Build() method. This allows to supply custom logger in build parameters, for example.