CODE INSIDE

FAKE: Build ASP.NET projects with web.config transformation (and without knowing a tiny bit of F#)

This is a follow-up to my other FAKE posts:

What’s the difference between a ASP.NET and other projects?

The most obvious difference is that the output is a bunch of dlls and content files. Additionally you might have a web.debug.config or web.release.config in your source folder.

Both files are important, because they are used during a Visual-Studio build as a Web.Config Transformation.

With a normal build the transformation will not kick in, so we need a way to trigger the transformation “manually”.

Project Overview

The sample project consists of one ASP.NET project and the .fsx file.

x

The “released” web.config should cover this 3 main transformation parts:

  • DefaultConnectionString to ‘ReleaseSQLServer’
  • No “debug”-attribute on system.web
  • developmentMode-AppSetting set to ‘true’

Web.Release.config

<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <connectionStrings>
    <add name="DefaultConnection"
      connectionString="ReleaseSQLServer"
      xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
  </connectionStrings>

  <appSettings>
    <add key="developmentMode" value="true" xdt:Transform="SetAttributes"
         xdt:Locator="Match(key)"/>
  </appSettings>
  
  <system.web>
    <compilation xdt:Transform="RemoveAttributes(debug)" />
  </system.web>
</configuration>

The FAKE script

We reuse the MSBuild-Helper from FAKE and inject a couple of “Publish”-related stuff, which will trigger the transformation.

A few remarks: In the “normal” WebDeploy-World you would have a PublishProfile and it would end up with a .zip-file and a couple of other files that fill in parameters like the ConnectionString. With this MSBuild command I mimik a part of this behavior and use the temporary output as our main artifact. In my most apps I use web.config transformations only for “easy” stuff (e.g. remove the debug attribute) - if you are doing fancy stuff and the output is not what you want, please let me know.

This MSBuild command should apply all your web.config transformations.

Publish a ASP.NET project

...
Target "BuildWebApp" (fun _ ->
trace "Building WebHosted Connect..."
!! "**/*.csproj"
 |> MSBuild artifactsBuildDir "Package"
    ["Configuration", "Release"
     "Platform", "AnyCPU"
     "AutoParameterizationWebConfigConnectionStrings", "False"
     "_PackageTempDir", (@"..\" + artifactsDir + @"Release-Ready-WebApp")
     ]
 |> Log "AppBuild-Output: "
)
...

“AutoParameterizationWebConfigConnectionStrings” or how to get rid of $(ReplacableToken_…

Blogpost updated on 2016-07-18

A friend told me that his transformed web.config contained “$(ReplaceableToken_…)” strings. It seems that “connectionStrings” are treated specially. If you have a connectionString in your web.config and don’t set “AutoParameterizationWebConfigConnectionStrings=False” you will get something like that:

<connectionStrings>
  <!-- Not the result we are looking for :-/ -->
  <add name="DefaultConnection" connectionString="$(ReplacableToken_DefaultConnection-Web.config Connection String_0)" providerName="System.Data.SqlClient" />
</connectionStrings>

I would say this is not the result you are expecting. With the “AutoParameterizationWebConfigConnectionStrings=False” parameter it should either do a transformation or leave the default-connectionString value in the result.

Thanks to Timur Zanagar! I completely missed this issue.

Result

x

This build will produce two artifacts - the build-folder just contains the normal build output, but without a web.config transformation.

The other folder contains a ready to deploy web application, with the web.release.config applied.

<connectionStrings>
  <add name="DefaultConnection" connectionString="ReleaseSQLServer" providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
  ...
  <add key="developmentMode" value="true" />
</appSettings>
<system.web>
  ...
</system.web>

You can find the complete sample & build script on GitHub.

blog comments powered by Disqus