HowTo: Web.config Transformations with MSBuild

 

imageWith Asp.NET 4.0 a new feature named “Web.config Transformations“ was released. During my latest MSBuild Posts I showed you how to for example build a solution with pure MSBuild. Usually the web.config isn´t triggered and the WebApp works in debug Mod (worst case!). Because of this we need to trigger it manual in MSBuild.

 

How the output looks like till now

Take a look on this post to find out how to create a _PublishedWebsites folder where the WebApp. could be founded. But here you will find the Transformation-files too:

 

image

The main problem: The transformation of the mainly web.config doesn´t happen – the application runs with debug:

    <compilation debug="true" targetFramework="4.0">

and then the call will look like this:

	<TransformXml Source="Web.config"
				  Transform="Web.Release.config"
				  Destination="Web.transformed.config" />

BUT: that sucks! Am I right?

In the end I want the transformed file with the name “web.config”. the problem: TransformXml is buggy. During the build the task locked these 3 files. Anyway: We don´t want to change our web.config file in our solution. Because of this we need to create a copy of our sources and change them.

Scheme:

image

CopySource:

We copy our whole sources to another place for example one folder back in our own directory. I named it “ClientTemp”.

image

BeforeCompile:

Here in the BeforeCompile targets, which are located in Clienttemp, I´m able to do some changes like for example changing the AssemblyVersion while opening. At this place I´m used to open the TransformXml Task as well:

	<TransformXml Source="..\MsBuildSample.WebApp\Web.config"
				  Transform="..\MsBuildSample.WebApp\Web.$(Configuration).config"
				  Destination="$(BuildDirFullName)MsBuildSample.WebApp\Web.config" />

Source&Transform are from the original branch and because of this we don´t need to take care of the lock.

Just the destination could be founded in our “cloned” folder. After this the “web.config” is transformed.

Build:

Here the mainly building process begins. The standard behavior is going to build the solution and pass the WebApp into the _PublishedWebsites OutDir.

Some other actions are able to follow. I´m going to delete the unused transformation files from the OutDir. (web.release.config / web.debug.config).

Result

It becomes a little bit trickier but the structure has her advantages as well. With this I´m able to work on my code during the building process (and before the compile) without changing the Source Code. It reminds me ( a little, little bit ;) of the functionality of TFS.

Complete buildscript:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Run">
<Import Project="$(MSBuildStartupDirectory)\Lib\MSBuild.Community.Tasks.Targets"/>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
   <PropertyGroup>
	<!-- After Compile: Result will be saved in OutDir -->
		<OutDir>$(MSBuildStartupDirectory)\..\..\ClientTemp\OutDir\</OutDir>

	<!-- Name of the BuildDir with the whole source code before the compile begins -->
		<BuildDirName>BuildDir</BuildDirName>

	<!-- Relativ part of the BuildDir -->
	<BuildDirRelativePart>..\..\ClientTemp\$(BuildDirName)</BuildDirRelativePart>

	<!-- Absolute part of the BuildDir-->
	<BuildDirFullName>$(MSBuildStartupDirectory)\$(BuildDirRelativePart)\</BuildDirFullName>

	<!-- Configuration -->
	<Configuration>Release</Configuration>

	<!-- Solutionproperties-->
		<SolutionProperties>
			OutDir=$(OutDir);
			Platform=Any CPU;
			Configuration=$(Configuration)
		</SolutionProperties>
   </PropertyGroup>
	<ItemGroup>
		<Solution Include="$(BuildDirFullName)MsBuildSample.sln">
			<Properties>
				$(SolutionProperties)
			</Properties>
		</Solution>
	</ItemGroup>
	<Target Name="Run">
	<Message Text="Run called." />

	<CallTarget Targets="CopyToBuildDir" />
	<CallTarget Targets="BeforeBuild" />
	<CallTarget Targets="Build" />
	<CallTarget Targets="Cleanup" />
	<CallTarget Targets="Zip" />
  </Target>
  <Target Name="CopyToBuildDir">
	<Message Text="CopyToBuildDir called." />
	<Exec Command="robocopy .. $(BuildDirRelativePart) /s /z /purge /a-:r" ContinueOnError="true" />
  </Target>
	<Target Name="BeforeBuild">
	<Message Text="BeforeBuild called." />

	<Message Text="Transform Xml" />
	<TransformXml Source="..\MsBuildSample.WebApp\Web.config"
									Transform="..\MsBuildSample.WebApp\Web.$(Configuration).config"
									Destination="$(BuildDirFullName)MsBuildSample.WebApp\Web.config" />
  </Target>

  <Target Name="Build">
	<Message Text="Build called." />
	<MSBuild Projects="@(Solution)"/>
	</Target>

	<Target Name="Cleanup">
		<Delete Files="$(OutDir)_PublishedWebsites\MsBuildSample.WebApp\Web.Release.config" />
		<Delete Files="$(OutDir)_PublishedWebsites\MsBuildSample.WebApp\Web.Debug.config" />

	</Target>
  <ItemGroup>
	<ZipFiles Include="$(OutDir)_PublishedWebsites\**\*.*" />
  </ItemGroup>
  <Target Name="Zip">
	<Zip Files="@(ZipFiles)"
			 WorkingDirectory="$(OutDir)_PublishedWebsites\"
			 ZipFileName="$(OutDir)Package.zip"/>
  </Target>
</Project>
 

Democode:

In my demosolution I work with some help variables of MSBuild – don´t be scared ;)

If you open the Samplecode:

D:\Samples\MsBuildSample ablegt findet Ihr das “BuildVerzeichnis” in D:\Samples\ClientTemp

[Download Democode]

If you enjoyed this post, please consider leaving a comment or subscribing to the RSS feed to have future articles delivered to your feed reader.

About the author

Written by Code Inside Team

Learn more about our team.

Comment on this post

Recent Posts

  • Automated Security Analyser for ASP.NET websites

    Evil Hackers are lurking everywhere and many Web-applications are delicately and share “too much” with the attacker. A quick (first!) overview offers the Tool “ASafaWeb”. All the website does is making a few requests and writing an Analyses including problem solving’s. There are no permanent disadvantages (bad requests/ DoS attacks and so on). Example: KnowYourStack.com ...

  • image1489-570x194.png
    „Sign in with Twitter“ for your own ASP.NET WebApp

      “Sign in with Twitter” is a popular practice to authenticate the users on your website. One advantage compared to an own registration is the lower inhibition for the user. But on the other hand Twitter doesn’t fess up with all the information’s and you will get into a kind of addiction. At the end ...

  • image1485-570x194_thumb.png
    CodePlex is going to be updated

      CodePlex the Microsoft Open Source Project Hosting Plattform hasn’t changed that much in the last few years and for a few times I thought Microsoft stopped the whole developing process. But now I found out that there is still life in the project. Maybe it is because of the success of GitHub or because ...

  • image1474_thumb.png
    What does Adobe in the flash-free web? Magazine-Style Layouts with CSS Regions!

      Adobe is well known for Photoshop and Flash but of course there is a lot more. According to the “Future Post” from Google Adobe declared one of their big subjects on a Blogpost. I’m talking about the W3C Working Draft to CSS Regions. Adobe cooperates with the WebKit Team and W3C on this. What ...

  • image1471-523x194.png
    HTML 5 Games, Tooling & 3D

      Game Developing is an interesting subject for all kind of software developer. But as a web developer without any Flash-skills there aren’t that much starting points. With HTML5 and the combination between Javascript, CSS3 and fast browsers there are the first “robust” HTML5 games. HTML5 games? Is this real? Neowin created a “Top 10” ...

Support us