- | rssFeed | My book on MSBuild and Team Build | Archives and Categories Monday, September 14, 2009

ASP.NET MVC: Build Views

If you are using ASP.NET MVC you might have noticed that you will not be alerted of build errors that exist in your views until you navigate to those pages. When you do so you'll get a runtime error L Thankfully there is a very easy way to change this. All you have to do is open the project file and change the value for the MvcBuildViews property to true. To do this, follow these steps.

  1. Right-click on the MVC project and select 'Unload Project'
  2. Right-click on the unloaded MVC project and select 'Edit …'. This will open up the project file itself, which of course is an MSBuild file.
  3. Look for the MvcBuildView property and set its value to true. It should be <MvcBuildViews>true</MvcBuildViews>
  4. Save the project file, right-click on the MVC project again and select 'Reload project'

After this if you introduce any build errors into the views then you will be notified when the project is built.

Sayed Ibrahim Hashimi

ASP.NET MVC | msbuild Monday, September 14, 2009 5:37:16 AM (GMT Daylight Time, UTC+01:00)  #     | 
Friday, September 4, 2009

Speaking at Tallahassee Code Camp

This weekend I will be speaking at the Tallahassee Code Camp on Saturday September 5, 2009. I will be presenting two sessions which are:

ASP.NET Custom View Helpers

If you have been using ASP.NET MVC then you certainly have been using some of the built in
view helper methods that are available, you know those expressions like
Html.TextBox("textBoxName")
and Html.ValidationMessage("Required").
View helpers are nothing more than extension methods which create HTML that is injected into
your views based on the method and its parameters. Creating your own view helpers is very
simple and can be extremely beneficial. By writing your own custom view helpers you will
benefit in at least the following ways

  • Simplifies Your Views
  • Easies Rehydrating HTML Elements with ModelState Values
  • Standardizes the Creation of Common HTML Components
  • Helps you Implement the DRY (Don't Repeat Yourself) Principal

We will take an in depth look at how you can easily and effectively create your own view helpers. We will also discuss how the default view helpers were created and the benefits that they provide.

Utilizing Web Deployment Projects

In this session we will take a look at how Web Deployment Projects can be used to assist in the deployment of web sites and web applications; including ASP.NET Web Applications and ASP.NET MVC Web Applications. We will give an overview of what Web Deployment Projects are and the functionality that is available out of the box. A Web Deployment Project is a wrapper for the aspnet_compiler.exe tool in the form of an MSBuild project and adds value to using the tool itself. Because they are MSBuild files we are able to customize and extend the process. We will discuss how we can customize the process to perform common steps such as

  1. Creating Virtual Directories
  2. Updating values in the web.config file
  3. Encrypting the web.config file
  4. Minimizing JavaScript files
  5. Versioning the Assemblies

 

If you are in the area and interested in these topics make sure to drop in!

Sayed Ibrahim Hashimi

ASP.NET MVC | msbuild | speaking | Web Deployment Projects Friday, September 4, 2009 5:40:20 AM (GMT Daylight Time, UTC+01:00)  #     | 
Wednesday, August 26, 2009

Speaking at St. Louis Day of .NET

On Friday August 28 and Saturday August 29 there will be a conference in St. Louis called St. Louis Day of .NET that I will be speaking at. Here is the outline

Simplify build and deployment of ASP.NET sites with Web Deployment Projects

When you are creating ASP.NET sites, (either ASP.NET web site / ASP.NET Web Project / ASP.NET MVC Project / etc) you will need to deploy the site to machines which will host them. Classically there were two options; xcopy the actual source to the live server and let them be compiled on demand or you could use the aspnet_compiler.exe and aspnet_merge.exe tools to pre-compile the website for you. The little known, yet extremely useful, Web Deployment Projects (an add on for Visual Studio) can greatly simplify the process of build and deployment. Web Deployment Projects will take care of the complexities of the aspnet_compiler.exe and the aspnet_merge.exe tool for you by way of a tight UI integration into Visual Studio itself. Aslo Web Deployment Projects are MSBuild files so you can extend and customize the process to suit your exact needs. In this session we will introduce Web Deployment Project, show that you can perform very powerful actions without writing a single line of code (or even text)! We will also dive into the MSBuild file that is the Web Deployment Project and show how to customize the process.

This session talks about Web Deployment Projects (2005 version) and how they can help in the build and deployment process. If you are going to be attending and interested in build and deployment of ASP.NET web sites and projects then you don't want to miss this session.

Sayed Ibrahim Hashimi

Deployment | msbuild | speaking | Web Deployment Projects Wednesday, August 26, 2009 4:19:16 AM (GMT Daylight Time, UTC+01:00)  #     | 
Monday, June 29, 2009

MSBuild Team Reviews Book

The other day Dan Moseley from the MSBuild team wrote up a review on the books Amazon page. Here are the contents of the review

I'm a developer on MSBuild; Sayed wrote this book with our encouragement, and we reviewed it for accuracy and completeness, so I can recommend it. The documentation for MSBuild in 2.0 and 3.5 was not great; I consider this something like the missing manual. Unfortunately there aren't many other MSBuild books; fortunately Sayed did a good job on this one.

We're fixing a lot of what's "missing" in MSBuild in the upcoming version 4.0 -- I hope Sayed can do a 2nd edition when that comes out. Plus, our docs should be better then :-)

I'm glad to say that this review was posted as 5 out of 5 and that is the 9th review (out of 9) which has been given 5 stars. When we wrote the book I knew that we had put something together that would really meet a specific need. I'm happy to see that the book has been accepted soo well by everyone and I hope that we are able to write a second edition as Dan mentioned.

Sayed Ibrahim Hashimi

book | msbuild | review Monday, June 29, 2009 4:31:19 AM (GMT Daylight Time, UTC+01:00)  #     | 
Wednesday, June 3, 2009

MSBuild Code Review

A long time ago a reader sent me a build script and asked for my thoughts on it. This is my response. In this entry I have marked up his build script with my comments inside of tags like:

  <!-- ****************************************

      My comments inside of these

  ********************************************* -->

I thought that you guys might be interested in this too. Here it is.

< Project DefaultTargets = " Build " xmlns = " http://schemas.microsoft.com/developer/msbuild/2003 " >

 

 

  <!-- ****************************************

  You can pull these out into a seperate file, i.e., CompanyName.BuildTasks.tasks

  ********************************************* -->

   < UsingTask TaskName = " BuildTasks.MoveUpBuildNumber " AssemblyFile = " BuildTasks\bin\Debug\BuildTasks.dll " />

  < UsingTask TaskName = " BuildTasks.ReplaceInFile " AssemblyFile = " BuildTasks\bin\Debug\BuildTasks.dll " />

  < UsingTask TaskName = " BuildTasks.CheckInIntoVSS " AssemblyFile = " BuildTasks\bin\Debug\BuildTasks.dll " />

  < UsingTask TaskName = " BuildTasks.CheckOutFromVSS " AssemblyFile = " BuildTasks\bin\Debug\BuildTasks.dll " />

  < UsingTask TaskName = " BuildTasks.UndoCheckOutFromVSS " AssemblyFile = " BuildTasks\bin\Debug\BuildTasks.dll " />

  < UsingTask TaskName = " BuildTasks.GetLatestFromVSS " AssemblyFile = " BuildTasks\bin\Debug\BuildTasks.dll " />

  < UsingTask TaskName = " BuildTasks.LabelInVSS " AssemblyFile = " BuildTasks\bin\Debug\BuildTasks.dll " />

  < UsingTask TaskName = " BuildTasks.ShowMessageBox " AssemblyFile = " BuildTasks\bin\Debug\BuildTasks.dll " />

 

 

 

  <!-- ****************************************

  In order to create more extensible MSBuild files you should place conditions on Properties.

  For example:

 

  <PropertyGroup Condition="'$(VSSDatabasePath)'==''">

    <VSSDatabasePath>\\rataserv\vss\srcsafe.ini</VSSDatabasePath>

  </PropertyGroup>

 

  When you do this users can create another file, i.e., MyCustomBuild.proj which imports your

  file and just overrides a few values.

  ********************************************* -->

  < PropertyGroup >

    < VSSDatabasePath > \\some\path\here\srcsafe.ini </ VSSDatabasePath >

  </ PropertyGroup >

  <!-- ======================================================================================== -->

 

  <!-- ****************************************

  Also for extensibility your DependsOnTargets should always be pulled from a property

  which pre-prendes its values to the property itself. So that is:

 

  <PropertyGroup>

    <BuildDependsOn>

      PrebuildAndRun;

      CheckInDeliverables;

      $(BuildDependsOn);

    </BuildDependsOn>

  </PropertyGroup>

 

  In this manner external files can extend the behavior of the Build target. Without this it is going

  to be difficult for people to effectively customize the build process.

  ********************************************* -->

  < Target Name = " Build " DependsOnTargets = " PrebuildAndRun;CheckInDeliverables " >

  </ Target >

 

  <!-- ****************************************

  Be careful with names. I would recommend using a naming convention that will ensure

  that your Targets/Properties/Items do not collide with each other.

  For example if I create re-usable .targets files and many of them have a "Build" target

  then I cannot user more than 1 at a time via an <Import ..>. Which is how I like for

  reusable .targets files to be used. For example using a prefix such as in my case SedoConfig or SedoDB.

  Do I need to expand on this?

  **************************************** -->

 

  <!-- ****************************************

  All "Important" targets should have Before and After targets which are on

  the DependsOnTargets property. So that would be:

 

 

  <PropertyGroup>

    <BuildDependsOn>

      BeforeBuild;

      PrebuildAndRun;

      CheckInDeliverables;

      AfterBuild;

      $(BuildDependsOn);

    </BuildDependsOn>

  </PropertyGroup> 

 

  <Target Name="Build" DependsOnTargets ="$(BuildDependsOn)"/>

  <Target Name="BeforeBuild"/>

  <Target Name="AfterBuild"/>

  **************************************** -->

 

 

  <!-- ****************************************

  All the files that you need to checkout can be placed inside of an item and then

  you can batch the usage of the BuildTasks.CheckOutFromVSS task. The item would

  have to have custom metadata of DatabasePath, FilePathInVss and WorkingDirectory.

  So that would be:

 

  <ItemGroup>

    <FilesToCheckOut Include="BuildNumberLP.txt">

      <DatabasePath>$(VSSDatabasePath)</DatabasePath>

      <FilePathInVSS>$/Source/src/LP/BuildNumberLP.txt</FilePathInVSS>

      <WorkingDirectory>LP</WorkingDirectory>

    </FilesToCheckOut>

    <FilesToCheckOut Include="DatabasePackages.sql">

      <DatabasePath>$(VSSDatabasePath)</DatabasePath>

      <FilePathInVSS>$/Source/src/LP/DatabaseScripts/DatabasePackages.sql</FilePathInVSS>

      <WorkingDirectory>LP/DatabaseScripts</WorkingDirectory>

    </FilesToCheckOut>

   

  </ItemGroup>

  <Target Name="PrebuildAndRun">

   

    <BuildTasks.CheckOutFromVSS

      DatabasePath="%(FilesToCheckOut.DatabasePath)"

      FilePathInVSS="%(FilesToCheckOut.FilePathInVSS)"

      WorkingDirectory="%(FilesToCheckOut.WorkingDirectory)"

   />

 

 

  </Target>

  **************************************** -->

 

  <!-- ****************************************

    The value for DatabasePath probably could just be taken from $(VSSDatabasePath)

    still. It depends on if you might pull files from more than one repository.

    **************************************** -->

 

  < Target Name = " PrebuildAndRun " >

    < Message Text = " building $(MSBuildProjectFile) " Importance = " high " />

    < Message Text = " ------ PATCHING FILES WITH BUILD NUMBER " Importance = " high " />

    <!-- check out file that stores the version incremented on each release build -->

    < BuildTasks.CheckOutFromVSS

      DatabasePath = " $(VSSDatabasePath) "

      FilePathInVSS = " $/Some/Path/Here/BuildNumberLP.txt "

      WorkingDirectory = " LP "

   />

    <!-- check out source files we gonna patch -->

    < BuildTasks.CheckOutFromVSS

      DatabasePath = " $(VSSDatabasePath) "

      FilePathInVSS = " $/Some/Path/Here/DatabaseScripts/DatabasePackages.sql "

        WorkingDirectory = " LP/DatabaseScripts "

   />

    < BuildTasks.CheckOutFromVSS

      DatabasePath = " $(VSSDatabasePath) "

      FilePathInVSS = " $/Some/Path/Here/AssemblyInfo.cs "

      WorkingDirectory = " LP "

   />

    < BuildTasks.CheckOutFromVSS

      DatabasePath = " $(VSSDatabasePath) "

      FilePathInVSS = " $/Some/Path/Here/Properties/AssemblyInfo.cs "

      WorkingDirectory = " LPinstaller/Properties "

   />

    <!-- check out deliverables -->

    < BuildTasks.CheckOutFromVSS

      DatabasePath = " $(VSSDatabasePath) "

      FilePathInVSS = " $/Some/Path/Here/Release/LPSetup.msi "

      WorkingDirectory = " LPSetup/Release "

   />

    < BuildTasks.CheckOutFromVSS

      DatabasePath = " $(VSSDatabasePath) "

      FilePathInVSS = " $/Some/Path/Here/Release/setup.exe "

      WorkingDirectory = " LPSetup/Release "

   />

 

 

    <!-- ****************************************

    The value passed to file could be taken from a property

    so that it can be overridden by another user.

    **************************************** -->

    <!-- PATCH!  -->

    < BuildTasks.MoveUpBuildNumber

    File = " LP/BuildNumberLP.txt " >

      < Output TaskParameter = " BuildNumber " PropertyName = " BuildNumber " />

    </ BuildTasks.MoveUpBuildNumber >

 

    <!-- <Message Text="Build number for the new build will be:$(BuildNumber)" Importance="high" /> -->

    < BuildTasks.ReplaceInFile

        SearchString = " PACKAGE_REVISION "

        ReplaceString = " $(BuildNumber) "

        FileName = " LP/DatabaseScripts/DatabasePackages.sql "

   />

    < BuildTasks.ReplaceInFile

        SearchString = " 27857 "

        ReplaceString = " $(BuildNumber) "

        FileName = " LP/AssemblyInfo.cs "

   />

    < BuildTasks.ReplaceInFile

        SearchString = " 27857 "

        ReplaceString = " $(BuildNumber) "

        FileName = " LPinstaller/Properties/AssemblyInfo.cs "

   />

    < Message Text = " ------ PATCHING FILES WITH BUILD NUMBER... DONE " Importance = " high " />

    <!-- ****************************************

    To get to devenv you could also use:

      $(VS80COMNTOOLS)..\IDE\devenv.com</Devenv>

    **************************************** -->

    <!-- ====================================== -->

    <!-- now build the entire solution including the setup packaging in release mode -->

    <!-- <MSBuild Projects="LP/LP.SLN" Properties="Configuration=Release"/> -->

    < Exec Command = " &quot; C:\Program Files\Microsoft Visual Studio 8\Common7\IDE/devenv.com &quot; &quot; .\LP\LP.SLN

      &quot; /build &quot; Release &quot; /project ..\LPSetup\LPSetup.vdproj /projectconfig &quot; Release &quot; " />

    <!-- ====================================== -->

    < OnError ExecuteTargets = " RecoverFromError " />

  </ Target >

  <!-- ======================================================================================== -->

  < Target Name = " CheckInDeliverables " >

 

 

    <!-- ****************************************

    You could use the same item as you used in the BuildTasks.CheckOutFromVSS

    step here.

    **************************************** -->

    < Message Text = " ------ CHECKING IN CHANGED FILES " Importance = " high " />

    <!-- check the file with new version back into VSS -->

    < BuildTasks.CheckInIntoVSS

      DatabasePath = " $(VSSDatabasePath) "

      FilePathInVSS = " $/Some/Path/Here/LP/BuildNumberLP.txt "

      WorkingDirectory = " LP "

   />

    <!-- ****************************************

    Since you are performing two different actions CheckIn and UndoCheckout

    you would need another piece of metadata on the item lets say, i.e. CheckInAfterEdit,

    then on your CheckInIntoVSS task usage you would place the condition

       Condition="'%(FilesToCheckOut.CheckInAfterEdit)'=='true'"

    that way you would create a batch of files to check in and pass it to the task.

    On your UndoCheckOut you would jus inver the == to !=.

    **************************************** -->

    <!-- revese the assemblies and script files to the "search  marker" that

    gets updated on patching by the build version -->

    < BuildTasks.UndoCheckOutFromVSS

      DatabasePath = " $(VSSDatabasePath) "

      FilePathInVSS = " $/Some/Path/Here/DatabaseScripts/DatabasePackages.sql "

      WorkingDirectory = " LP/DatabaseScripts "

   />

    < BuildTasks.UndoCheckOutFromVSS

      DatabasePath = " $(VSSDatabasePath) "

      FilePathInVSS = " $/Some/Path/Here/LP/AssemblyInfo.cs "

      WorkingDirectory = " LP "

   />

    < BuildTasks.UndoCheckOutFromVSS

      DatabasePath = " $(VSSDatabasePath) "

      FilePathInVSS = " $/Some/Path/Here/LPinstaller/Properties/AssemblyInfo.cs "

      WorkingDirectory = " LPinstaller/Properties "

   />

    <!-- checkin deliverables we just built  -->

    < BuildTasks.CheckInIntoVSS

      DatabasePath = " $(VSSDatabasePath) "

      FilePathInVSS = " $/Some/Path/Here/Release/LPSetup.msi "

      WorkingDirectory = " LPSetup/Release "

   />

    < BuildTasks.CheckInIntoVSS

      DatabasePath = " $(VSSDatabasePath) "

      FilePathInVSS = " $/Some/Path/Here/Release/setup.exe "

      WorkingDirectory = " LPSetup/Release "

   />

    <!-- Label as the new version  -->

    < BuildTasks.LabelInVSS

      DatabasePath = " $(VSSDatabasePath) "

      FilePathInVSS = " $ "

      Label = " Revision $(BuildNumber) "

   />

    < Message Text = " ------ CHECKING IN CHANGED FILES... DONE " Importance = " high " />

    < OnError ExecuteTargets = " ErrorOnCheckIn " />

  </ Target >

  <!-- ======================================================================================== -->

  < Target Name = " RecoverFromError " >

    < Message Text = " An error has occurred, reversing checkouts " />

    < BuildTasks.UndoCheckOutFromVSS

      DatabasePath = " $(VSSDatabasePath) " IgnoreError = " true "

      FilePathInVSS = " $/Some/Path/Here/LP/AssemblyInfo.cs "

      WorkingDirectory = " LP "

   />

    < BuildTasks.UndoCheckOutFromVSS

      DatabasePath = " $(VSSDatabasePath) " IgnoreError = " true "

      FilePathInVSS = " $/Some/Path/Here/LP/BuildNumberLP.txt "

      WorkingDirectory = " LP "

   />

    < BuildTasks.UndoCheckOutFromVSS

    DatabasePath = " $(VSSDatabasePath) " IgnoreError = " true "

    FilePathInVSS = " $/Some/Path/Here/DatabaseScripts/DatabasePackages.sql "

    WorkingDirectory = " LP/DatabaseScripts "

   />

    < BuildTasks.UndoCheckOutFromVSS

      DatabasePath = " $(VSSDatabasePath) " IgnoreError = " true "

      FilePathInVSS = " $/Some/Path/Here/LPinstaller/Properties/AssemblyInfo.cs "

      WorkingDirectory = " LPinstaller/Properties "

   />

    < BuildTasks.UndoCheckOutFromVSS

      DatabasePath = " $(VSSDatabasePath) " IgnoreError = " true "

      FilePathInVSS = " $/Some/Path/Here/Release/LPSetup.msi "

      WorkingDirectory = " LPSetup/Release "

   />

    < BuildTasks.UndoCheckOutFromVSS

      DatabasePath = " $(VSSDatabasePath) " IgnoreError = " true "

      FilePathInVSS = " $/Some/Path/Here/Release/setup.exe "

      WorkingDirectory = " LPSetup/Release "

   />

  </ Target >

  <!-- ======================================================================================== -->

  < Target Name = " ErrorOnCheckIn " >

    <!-- ****************************************

    Does this actually show a message box? If so you should place a condition on this task

    usage here to make sure that this can be disabled so that the builds can be automated.

    **************************************** -->

    < BuildTasks.ShowMessageBox Message =

        " Build process failed to check in the files for the new build or reverse checkouts.

        Make sure that all files are checked in and retry the build. " />

  </ Target >

</ Project >

 

Sayed Ibrahim Hashimi

msbuild | review Wednesday, June 3, 2009 4:25:21 AM (GMT Daylight Time, UTC+01:00)  #     |