The point of this post
In a default ASP.NET project configuration, all files (except code-behind files) included in a project are copied to the target location when publishing a project or creating a deployment package.
However, quite often we need to customize this behavior to suit our specific projects, especially when setting up automated builds - for example for continuous integration or for when we do a manual publish from within Visual Studio.
The Publish command is actually quite useful, and I just wrote a brief summary on how to deploy a website to a remote server using the Publish command in Visual Studio.
This post goes through some project modifications to include additional files, and also to exclude specific folders, when a website is published or when a deployment package is created.
Copy additional files not included in the project
There are times when you want to include files that are not included in the project. One example is when you have files that are created when the project is compiled, such as during post-build events.
Including additional files in publish and deploy scenarios
To include additional files not included in the project we’ll add some XML declarations to the .csproj project file. To edit it in Visual Studio we first right-click the project node in Solution Explorer and select Unload Project:
Next we right-click the project node again and click Edit [project file name] to manually edit the project file (you could also manually edit the .csproj file through Notepad or your preferred editing tool):
Next, we locate the line that says:
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
To copy additional files when our project is published (or deployed through an automated build) we define an additional MSBuild target called CustomCollectFiles beneath the <Import> element above. This target extends the CopyAllFilesToSingleFolderForPackageDependsOn target (phew!) which controls which files are copied in a publish or deploy scenario.
<CompressedScripts Include="Static\js\*.min.js" />
<!-- Copy minified stylesheets -->
<CompressedStylesheets Include="Static\css\*.min.css" />
Note that for each group of files we first declare an element with a name for the group, such as <CompressedScripts>. This is now a variable that we can use for the <FilesForPackagingFromProject> element, above seen as %(CompressedScripts.Identity).
When we’re done modifying our project file we right-click the project node in Solution Explorer and click Reload Project.
Now, if we choose to Publish the project…
…it’s still included among the published files:
Exclude specific project folders
We often add multiple resource folders to our projects, and by convention we name them inside brackets:
Although required for development, we don’t want these folders to be included when the website is published. So, we edit our project file like we did for file inclusion earlier, but instead we add one or more <ExcludeFromPackageFolders> elements inside an <ItemGroup> element.
The following ensures the three resource folders above are excluded from publish and deployment package scenarios:
Now, even though multiple folders are included in our project…
…they’re not included when the website is published:
Note: a side-effect of excluding folders this way is that the folder names will be displayed twice in Solution Explorer, I haven’t figured out if there’s a way around this.