There are already some very good articles that explain how to use a Web Deployment Project (for example Rick Strahl's article at http://www.west-wind.com/WebLog/posts/5601.aspx), but you can encounter some problems when trying to use a WDP on a Web Application Project with VS2005. This article explains the problems that I've encountered and their solutions.
You'll need to know what Web Application Projects (http://msdn2.microsoft.com/nl-be/asp.net/aa336618(en-us).aspx) and Web Deployment Projects (http://msdn2.microsoft.com/nl-be/asp.net/aa336619(en-us).aspx) are.
I lost a lot of time in the last few days trying to figure out whether I should be using a Web Deployment Project (WDP) to deploy a Web Application Project (WAP) created in VS2005. This article it to inform the community about what I've learned.
I wanted to deploy a Web Application Project using a single assembly and didn't really find any documentation that explains whether or not I still need to use a WDP for that because a WAP also compiles to a single assembly. As explained by Rick Strahl in http://www.west-wind.com/WebLog/posts/5601.aspx for deployment it's best to use a WDP because a WAP doesn't compile your markup code, so your website might contain errors that you missed otherwise.
So, if the conclusion is that we should use a WDP, how to set it up? I simply added a WDP to my solution, configured it to merge all outputs to a single assembly and compiled. Visual Studio failed to compile with the error message 'aspnet_merge.exe exited with code 1'. There are several causes for this error as mentioned on http://forums.asp.net/t/990114.aspx. In my case, the cause was that the name of the output assembly had the same name as the WAP project. This is apparently not supported. Changing the name of the output assembly to something different solves this.
After this change, the WDP actually compiles, but you'll notice that the merged assembly won't contain any version information. Normally aspnet_merge should copy the information in AssemblyInfo.cs of our website to the merge assembly, but apparently there's a bug in aspnet_merge (I assume it's a bug that is) that causes aspnet_merge to only copy the AssemblyInfo.cs file if it's stored in an App_Code directory as it normally is with stock project websites. The solution there is to manually create an App_Code directory and move your AssemblyInfo.cs from the Properties folder to App_Code. Make sure that the Build Action of the AssemblyInfo.cs file is still set to Compile though. For some reason, it got changed to Content in my case which caused other problems.
Also, when you move AssemblyInfo.cs, be aware that the 'Assembly Information' button in the Application tab of the Project properties of your WAP can't be used anymore. This thing will create a new AssemblyInfo.cs file in the Properties folder and having two different AssemblyInfo.cs files will obviously cause other problems. If I remember correctly, the MSBUILD task AssemblyInfoTask for one will fail because of that.
So, at this point you have a WDP that compiles properly using Visual Studio 2005 and that contains the correct assembly version information. You'll notice however, that the build will fail if you try to do it using MSBUILD in TFS2005. The reason for this is explained by Aaron Hallberg on http://blogs.msdn.com/aaronhallberg/archive/2007/07/02/team-build-and-web-deployment-projects.aspx. I implemented the first workaround, which solved this problem:
Point the web deployment project to the overridden location of the web application output - right click on the WDP in Solution Explorer, select Open Project File, and modify the value of the SourceWebPhysicalPath property. You may want to conditionalize this property value such that the WDP will work both in the IDE and in a Team Build build. In Team Build v1, the following will typically do the trick:
<SourceWebPhysicalPath Condition=" '$(TeamBuildConstants)'=='' ">..\WebApplication1</SourceWebPhysicalPath>
<SourceWebPhysicalPath Condition=" '$(TeamBuildConstants)'!=''
(...Where WebApplication1 is replaced with the name of your WAP.)
The last thing that really got me confused is what to deploy. When I deployed a WDP of a stock project (the default website project type of Visual Studio) I always removed all assemblies except for the output assembly specified in the the WDP properties and I only deployed this one combined with all .compiled-files. This worked perfectly because in our case, all the other assemblies are installed in the GAC so there wasn't any point in deploying them locally.
Apparently, this doesn't work exactly the same way with a WAP. Even though you configure your WDP to output to a single assembly, you really need to deploy at least two assemblies to get your website to work, even if all referenced assemblies are in the GAC. You need to deploy the assembly created by the WDP as well as the assembly created by the WAP. The WAP assembly contains your code behind, the WDP assembly contains your markup. If you don't do that and you try to run your website it will constantly fail with the famous "has not been pre-compiled" error message.
Hope this helps somebody else, cause I lost a lot of time figuring this out.