How do I compile an ASP.Net MVC project using MSBuild? We use a Continuous Integration server to compile and deploy our applications. To keep things simple I created an MVC 1.0 project in VS2008. I immediately开发者_Go百科 created an MSBuild script file to compile it. I did not change any code in the project. The MSBuild script contained the following target.
<AspNetCompiler VirtualPath="/" PhysicalPath="C:\Development\mvc1\" TargetPath="c:\publish\xxx" Force="true" Debug="false" Updateable="true"
The MVC project sln file is contained in the c:\development\mvc1\ directory. I am running XP/Pro.
I am receiving an error ASPCONFIG: it is an error to use a section registered as allowDefintion='MachineToApplication' beyond application level.. I removed the authenication mode, membership provider, etc. from the web config file until I finally saw a different error message. I am now receiving an error message saying that the file '/views/shared/site.master' does not exist.
What is going on? Thanks in advance for your help!
Am I using the wrong MSBuild command?
If you compile your sln-file (msbuild mysolution.sln) or
<MSBuild Projects="msbuild mysolution.sln" Targets="Rebuild" ContinueOnError="false"
StopOnFirstFailure="false" /><!-- -d -errorstack -->
and the sln-file has the ASP.NET MVC-project .csproj-file then the .csproj-file does have everything you need. Open the .csproj with notepad and look for:
1) This should be true:
<MvcBuildViews>false</MvcBuildViews>
2) Target Name="AfterBuildCompiler":
<Target Name="AfterBuildCompiler" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="SomeVirtualDir" PhysicalPath="C:\Development\mvc1\" TargetPath="c:\publish\xxx\" />
</Target>
I didn't do anything else and it worked. I actually made my config so that only release build deploy the application (by moving MvcBuildViews-property under PropertyGroups. Then I can use the same .csproj in the development (debug) and deployment (release).
This build script compiles an asp.net MVC 3 application. Since the entire internet appears to have forgotten the concept of "Build Script" this one does not require you to have Visual Studio installed on the target Machine or to "lol, you just have to edit your csproj file to get msbuild!!"
Moving on.
Make sure you have .NET 4 and MVC3 installed. By the way, my build scripts only work with msbuild 4, so make sure you're using the proper one.
The general process is as follows (thanks to many hints and answers I got here!)
1) Build the dependencies (you DLL's)
2) Build the DLL for your web application.
3) Call the asp.net compiler task.
4) Check the scripts for additional comments.
Note that this is called from an outside script that compiles other DLL's (Business, data access, etc.)
<Project ToolsVersion="4.0" DefaultTargets="build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildDir>..\..\dist</BuildDir>
<Optimize>true</Optimize>
</PropertyGroup>
<ItemGroup >
<Reference Include="System.dll" />
<Reference Include="System.Core.dll" />
<Reference Include="System.Web.Abstractions.dll" />
<!-- add the remaining DLL's required. Check your References folder inside VS2010 and add the relevant entries here. It's a lot of references. I ommited them to make the post more compact.
For reasons that are beyond me, I only managed to get some DLL's referenced by full path. Go figure... -->
<Reference Include="C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Web.Helpers\v4.0_1.0.0.0__31bf3856ad364e35\System.Web.Helpers.dll" />
<Reference Include="C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Web.Mvc\v4.0_3.0.0.0__31bf3856ad364e35\System.Web.Mvc.dll" />
<Reference Include="C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Web.WebPages\v4.0_1.0.0.0__31bf3856ad364e35\System.Web.WebPages.dll" />
<!-- The "main build script" compiles the other DLL's from the project and places them on the BuildDir folder. Just reference it here-->
<Reference Include="$(BuildDir)\*.dll"></Reference>
</ItemGroup>
<!-- Build a DLL for the code file inside your web project (controllers, models, the lot...) place it together with the other DLL's
WARNING: Simple build command. Resource files are not included in this.
-->
<Target Name="BuildWebDll">
<ItemGroup>
<CodeFiles Include=".\**\*.cs" />
</ItemGroup>
<CSC Sources="@(CodeFiles)" TargetType="Library" References="@(Reference)" OutputAssembly="$(BuildDir)\cth.web.dll" >
</CSC>
</Target>
<!-- For reasons also unkown, but covered in a number os posts in this forum, the asp.net compiler requires the necessary DLL's to be placed on the BIN/ folder of your web project. That's why we're copying every DLL we need to said folder. For debugging, check the Bin folder on Visual Studio after you compile the project. You need to replicate that in your BIN/
-->
<Target Name="CopyDLLs">
<ItemGroup>
<DllFiles Include="$(BuildDir)/*.dll"/>
</ItemGroup>
<Copy SourceFiles="@(DllFiles)" DestinationFolder="Bin\"></Copy>
</Target>
<Target Name="build">
<CallTarget Targets="BuildWebDll"></CallTarget>
<CallTarget Targets="CopyDLLs"></CallTarget>
<!-- Call this from the webproject directory. PhysicalPath references ".". TargetPath can be everything you want -->
<AspNetCompiler Updateable="true" VirtualPath="/CTH.Web" PhysicalPath="./" TargetPath="$(BuildDir)/CTH.Web" Force="true" Debug="false" />
</Target>
Remember that you have to include resource files, do any web.config replacements, etc. I really hope this helps.
The easiest way I found was to add a WebDeployment project to your solution. http://www.microsoft.com/DOWNLOADS/details.aspx?FamilyID=0aa30ae8-c73b-4bdd-bb1b-fe697256c459&displaylang=en
You set the properties for the build in the WebDeployment project (like precompile ) . The Buildserver builds the wdprj.
In my environment I have to start by building the web first. After that I can start the wdprj.
Here is my nant - script. It should be easy to write the same in msbuild. It actually runs in TeamCity.
xml version="1.0"?>
<project name="GreatProjectWeb"
default="build" basedir="."
xmlns="http://nant.sf.net/release/0.85/nant.xsd">
<description>Build Script</description>
<!-- builds only the csproj, not the entire solution-->
<target name="build" description="Compile the project using Debug configuration for more verbose error descriptions">
<echo message="Building..."> </echo>
<exec program="C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe" >
<arg value="GreatProjectWeb\GreatProjectWeb.csproj" />
<arg value="/t:Build" />
<arg value="/p:Configuration=Release" />
</exec>
<echo message="Building Projektfile finished. Starting WDP Project..."> </echo>
<exec program="C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe" >
<arg value="GreatProjectWeb_Build\GreatProjectWeb_Build.wdproj" />
<arg value="/t:Build" />
<arg value="/p:Configuration=Release" />
</exec>
<exec program="7z" >
<arg value="a" />
<arg value="GreatProjectWeb_Deploy\web_GreatProject.zip" />
<arg value="GreatProjectWeb_Deploy\*" />
</exec>
</target>
</project>
You could use NAnt which has a "msbuild" task in it that will just do it for you. NAnt is a great way to go for CI builds.
The NAnt home page The NAnt Contrib home page The MSBuild task reference from NAnt Contrib
...the contrib library adds some great functionality that the vanilla NAnt doesn't have. It is very simple. I've included a snippet of my .build file here so you can see how I've used it:
<property name="DeployDestination" value="\\MyTestServerName\DestinationFolder"/>
<property name="Solution.Configuration" value="Debug" overwrite="True" />
<property name="nant.settings.currentframework" value="net-3.5" />
<if test="${WebContentDestination=='Production'}">
<property name="DeployDestination" value="\\MyProductionServer\DestinationFolder"/>
</if>
...<snip>
<target name="Build">
<msbuild project="SolutionFileName.sln">
<arg value="/p:Configuration=${Solution.Configuration}" />
</msbuild>
</target>
<target name="Deploy">
<copy todir="${DeployDestination}" flatten="true" >
<fileset>All files to copy</fileset>
</copy>
</target>
精彩评论