Is there a way to apply VS 2010 Web.Config transformations outside of web deployment, say during debugging? It would give me a great boost to be able to freely switch between different environments.
Asked
Active
Viewed 4,453 times
2 Answers
16
Yes, you can perform a Web.config transformation explicitly by invoking the TransformXml
MSBuild task during the AfterBuild
step in your project file.
Here's an example:
<UsingTask
TaskName="TransformXml"
AssemblyFile="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="AfterBuild" Condition="exists('Web.$(Configuration).config')">
<!-- Generates the transformed Web.config in the intermediate directory -->
<TransformXml
Source="Web.config"
Destination="$(IntermediateOutputPath)Web.config"
Transform="Web.$(Configuration).config" />
<!-- Overwrites the original Web.config with the transformed configuration file -->
<Copy
SourceFiles="$(IntermediateOutputPath)Web.config"
DestinationFolder="$(ProjectDir)" />
</Target>
Related resources:

Community
- 1
- 1

Enrico Campidoglio
- 56,676
- 12
- 126
- 154
-
This is a great method, and I have used it successfully. But I don't think he means on different projects. It sounds like it's web projects, but not during Web Deployment. – Kieren Johnstone Jun 22 '11 at 08:51
-
By applying that same solution, he'll be able to simply change the active build configuration and compile the project to have the Web.config transformed. In my experience just building a Web project won't perform a Web.config transformation. That step is done during packaging. However there's a way to force packaging on every build, by setting the `DeployOnBuild` MSBuild property to `true` in the project file. – Enrico Campidoglio Jun 22 '11 at 09:11
-
Huh, I checked the docs and I believe you're right. I am mistaken. – Kieren Johnstone Jun 22 '11 at 09:14
-
Can't get it to work with debugging. =( Should it really be on "AfterCompile"? – Jonn Jun 23 '11 at 03:08
-
@John I updated my answer with a slightly different solution. Let me know how it works for you. – Enrico Campidoglio Jun 23 '11 at 14:59
-
Close. I thought for sure that it'd work, but MSBuild can't copy it because it is being used by another process (which I'm assuming is itself). – Jonn Jun 24 '11 at 02:30
-
In this case you may have to copy the transformed Web.config file using xcopy in the Post-build event. I looked around and found [this thread](http://forums.asp.net/t/1532038.aspx/1?web+config+transformations+on+build+debug) where they talk about the exact same issue. – Enrico Campidoglio Jun 24 '11 at 06:10
-
I haven't gotten it fully yet. XD I'll mark this as answer though, at best it helped me copy paste a new transformed copy everytime I build so there's that. XD – Jonn Jun 27 '11 at 13:01
-
1This performs the transform on the actual source file; not a copy. Why would I want to do that for every build? It seems to me better to perform the transform on an intermediate copy of Web.config. My transform includes some `xdt:Transform="Insert"` so I end up with add'l elements every build... – Carl G Jan 16 '13 at 20:33
-
@CarlG Well, you cannot have multiple files named `Web.config` in the application's root directory, and ASP.NET will only consider those. However, you may take advantage of [configuration files inheritance](http://msdn.microsoft.com/en-us/library/ms178685(v=vs.100).aspx) to put the transformed `Web.config` in one of you project's subdirectories, for example where the views/pages are. – Enrico Campidoglio Jan 17 '13 at 15:12
-
2Yes but why not apply the transform in the build directory instead of the source directory? The source does not need to be transformed, only the build version of Web.config. The application ultimately looks at a Web.config next to it where the application is built, not int the root of the solution folder where we are working on source files. – Carl G Jan 17 '13 at 15:40
4
The solution above made a great starting point for me, but I ended up with the following which doesn't need a copy task and doesn't have any issues with file in use errors.
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="AfterBuild">
<TransformXml Condition="exists('$(TempBuildDir)\Web.$(Configuration).config')" Source="$(TempBuildDir)\Web.config" Destination="$(OutputPath)Web.config" Transform="$(TempBuildDir)\Web.$(Configuration).config" />
<ItemGroup>
<DeleteAfterBuild Include="$(OutputPath)Web.*.config" />
</ItemGroup>
<Delete Files="@(DeleteAfterBuild)">
<Output TaskParameter="DeletedFiles" PropertyName="deleted" />
</Delete>
<Message Text="DELETED FILES: $(deleted)" Importance="high" />
</Target>

Bernd
- 330
- 1
- 2
- 7
-
Why delete the files afterwards? Is there any danger of leaving them? Since the custom definition here doesn't copy them; just relies on MSBuild already having them present, why not just leave them? Thanks! – Carl G Jan 16 '13 at 20:31
-
1No real need, just a preference thing to keep the output clean of files that no longer have a purpose. – Bernd Mar 27 '13 at 19:24