Team Build and aspnet_compiler.exe

It's funny how things come in bunches sometimes...  I had never heard of the issue discussed in this blog post as of a couple of days ago, but we have received two queries on the topic in the Team Build forums in the last few days.  (Here they are, if you are interested:  One and Two

The issue deals with the compilation of websites, and particularly with *.aspx and *.ashx files (ashx files, by the way, are HTTP handlers).  In particular, when these types of files are compiled the resultant files typically contain some bogus text (something like "This is a marker file generated by the precompilation tool, and should not be deleted!"), while all the actual logic ends up in the generated assembly.  For example, the command line:

> aspnet_compiler.exe -v /WebApplication1 -p C:\MyProjects\WebApplication1 C:\MyProjects\WebApplication1\PrecompiledWeb

...will compile the web application defined in directory C:\MyProjects\WebApplication1 into the directory C:\MyProjects\WebApplication1\PrecompiledWeb.  In addition to using aspnet_compiler.exe directly, MSBuild includes the AspNetCompiler task.  The following MSBuild project file has the same result as the example command-line:

 <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="https://schemas.microsoft.com/developer/msbuild/2003" >
 <Target Name="Build">
     <AspNetCompiler VirtualPath="/WebApplication1" PhysicalPath="C:\MyProjects\WebApplication1" TargetPath="C:\MyProjects\WebApplication1\PrecompiledWeb" />
  </Target>
</Project>

Because Team Build typically compiles solutions and not projects, an additional complication is introduced with website projects.  By default, these projects have the -u option selected for their compilation in their solution property pages.  If you open up a solution containing a website project you should see a section that looks something like this:

Project("{Some GUID}") = "WebApplication1", ".\WebApplication1\", "{Some GUID}"
    ProjectSection(WebsiteProperties) = preProject
        Debug.AspNetCompiler.VirtualPath = "/WebApplication1"
        Debug.AspNetCompiler.PhysicalPath = ".\WebApplication1\"
        Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\WebApplication1\"
        Debug.AspNetCompiler.Updateable = "true"
        Debug.AspNetCompiler.ForceOverwrite = "true"
        Debug.AspNetCompiler.FixedNames = "true"
        Debug.AspNetCompiler.Debug = "True"
        VWDPort = "14091"
        DefaultWebSiteLanguage = "Visual C#"
    EndProjectSection
EndProject

Note the VirtualPath, PhysicalPath, and TargetPath lines - these specify options to the AspNetCompiler task that we have already seen in the above example (and correspond to the -v, -p, and targetPath options to aspnet_compiler.exe, respectively).  The rest of the lines with AspNetCompiler in them also correspond to AspNetCompiler task properties, and the Updateable (sic) property is the one we care about for this post - it corresponds to the -u option to aspnet_compiler.exe.

With this option turned on, aspnet_compiler.exe keeps markup, including inline code, in all *.aspx and *.ashx files (and possibly others - I'm no expert in these matters) so that they can be modified after the site is deployed.  So - if you compile your website projects by using MSBuild to compile the solutions that contain them:

> msbuild.exe C:\MyProjects\WebApplication.sln

...your *.aspx and *.ashx files will be updatable and will not be compiled.  Since Team Build typically compiles solutions, builds done through Team Build will run into the same issue.

So - to fix this issue, you can either manually edit your solution file (set the Debug.AspNetCompiler.Updateable value to "false" rather than "true", repeat for other configurations) in notepad, or you can edit it through the GUI by right-clicking on your website project, selecting Property Pages, selecting the MSBuild Options section, and unchecking the "Allow this precompiled site to be updated" box.