March 2012 Blog Posts
ASP.NET .refresh DLLs Not Updated (or copied) In WebDeployment .wdproj Projects

success_baby-kidThis is primarily used as notes for me …

As the title suggests, I had a problem with *some* DLL references inside Project.Web\Bin\*.refresh files not being copied during the .wdproj build process.

There were a few blogs out there that offered some solutions like editing the Microsoft.WebDeployment.targets file and removing the Copy “Condition” inside _ResolveReferences target (Line 862). But these solutions bothered me because it did not explain the root cause of the problem.

What was most strange about this problem was that all my builds worked before, so something must have goofed up the build process.

It turns out, your .wdproj file may be out-of-sync with your .SLN file. Double check the following XML elements inside your .wdproj file:

  • <SourceWebPhysicalPath> -- You need to triple check that this path is correct,
  • <SourceWebProject>GUID|ProjectURL/Name</SourceWebProject> -- The GUID in the <SourceWebProject> XML element must match the web-project GUID in your .SLN file. Also, the ProjectURL/Name should also match the string that follows the web-project GUID in your .SLN file too.

It turns out, if you were using Visual Studio’s built-in Cassini web server, then switched to IIS Express at a later date, your .wdproj may contain stale reference information located in the two XML tags listed above. Specifically, the format of the <SourceWebProject> tag using Cassini is “GUID|ProjectPath”, and “GUID|ProjectURL” for IIS Express. When you convert a website from Cassini to IIS Express, the website’s GUID changes and ProjectPath becomes ProjectURL in the .wdproj. The website GUID and ProjectURL values can be found inside the .SLN file after the change has been made.

If you’re unsure of what GUID|ProjectURL values are needed, simply remove the .wdproj deployment project from solution and add it again (overwriting your previous .wdproj), and Visual Studio will recreate the necessary values inside your .wdproj. Just remember to refresh your .wdproj when switching between IIS Express and Cassini.

Additional Tip 1

Double check your .SLN “E24C65DC-7377-472B-9ABA-BC803B73C61A” (Website Projects) sections of your .SLN file and ensure the AspNetCompiler.PhysicalPaths are correct.

Additional Tip 2

Make sure your website project is set to “build” in the Configuration Manager for your Release configuration.

image   image

This is important because, during the build process, MSBuild creates “meta projects” (.metaproj) for your website projects that are derived from your .SLN file. The reasoning is, website projects (which differ from Web Application projects) do not have an accompanying “.csproj” project file (which are essentially MSBuild scripts). Project settings for website projects are stored in the .SLN file and the .SLN file is used to create an intermediate (.metaproj) MSBuild script on-the-fly. You never see the resultant intermediate build script emitted from MSBuild by default.

To see the intermediate build script for your website project:

  • set MSBuildEmitSolution=1
    (via command-line - environment variable)
  • msbuild MyProject.sln /property:Configuration=Release /target:Rebuild
    (run MSBuild on your solution)

If your website project is set to build in Release configuration as shown in the pictures above, you should see a few files similarly named “localhost.metaproj” and “MyProject.sln.metaproj” emitted from MSBuild as it transformed your website project settings into intermediate MSBuild scripts. The “localhost.metaproj” files contain MSBuild tasks that read .refresh files and copy .refresh references into your Project.Web\Bin folder.

Ultimately, this will ensure all .refresh files are honored & copied before your .wdproj deployment build script executes.

Additional Tip 3

Ensure your website project and .wdproj has the correct build order in your solution:

image

Your .wdproj should be somewhat last and definitely after your website project build.

Additional Tip 4

If you want to avoid the extra aspnet_compile from enabling the “build” in tip 2 and you really feel up for modifying your Microsoft.WebDeployment.targets file, simply remove the ! operator from the Copy Condition in:

image

Removing the ! from the Copy Condition will copy the DLL references into your Web\Bin directory and all should be well.

Hope that helps,
Brian Chavez