Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Visual Studio 2010 config transform when running/debugging locally?

In the team I'm working in we have a big product with many WCF web services and some web sites which use the services. We are just about to upgrade to VS 2010 and I'm looking at if we should start using the new config transform functions in VS 2010.

We have several different environments which need different web.configs (database connection strings, WCF addresses and so on). Often when debugging something high up such as the web frontend it is useful to configure it to directly connect with the TEST or QA backend / databases. On each developer's local machine the IIS is configured directly to the source folder of each WCF/web project, and when running locally it is a simple matter of Ctrl-Shift-B or F5 to debug something. One would think that it would be possible to build/F5 with TEST or QA as configuration mode and get the TEST/QA config, but I don't see how. Is it not supported, or maybe we need to change how we work with things?

Our other option is to instead use a simple replace-script as a prebuild event that creates the web.config from a template and a key-file depending on configuration mode. With this method you would get TEST config if you compile in TEST and so on but it feels a bit bad to roll our own solution when there is a function built into Visual Studio.

like image 689
viblo Avatar asked Aug 06 '10 08:08

viblo


1 Answers

You can achieve the effect you're looking for by using the BeforeBuild and AfterBuild targets available in the .csproj file. The VS.NET IDE will execute these targets when doing a Build or a Rebuild, so you can use them to execute the web.config transforms. Since you'll need to do a web.config transform and then overwrite the actual web.config file, you'll need to rely on a new file called web.default.config to store the base web.config data.

I tried this out in a test project, here were the changes I made to the .csproj file:

<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
<ProjectExtensions>
...
</ProjectExtensions>
<Target Name="BeforeBuild">
    <Copy SourceFiles="$(ProjectDir)web.default.config" DestinationFiles="$(ProjectDir)web.config" />
</Target>
<Target Name="AfterBuild" Condition="$(FirstRun) != 'false'">
    <MSBuild Projects="$(MSBuildProjectFile)" Targets="TransformWebConfig" Properties="FirstRun=false;" />
    <Sleep Milliseconds="2000" />
    <Copy SourceFiles="$(ProjectDir)obj\$(ConfigurationName)\TransformWebConfig\transformed\web.config"
        DestinationFiles="$(ProjectDir)web.config" />
</Target>

I had to manually add these to the .csproj file (I used Notepad++). As far as I can tell there is no way to add these instructions through the VS.NET IDE. You need to supply the conditional on the AfterBuild to keep from having a circular reference, as the call to MSBuild will rerun the build to generate the web.config transform.

Basically what we're doing is copying the web.default.config file (our base template) over the existing web.config before we start to build, and then we use MSBuild to generate a web.config for whatever configuration we're building. After the transform is complete, we use a Copy task to take the transformed file and copy it over to the web.config file in the web root. One issue I occasionally ran into was a file in use error when trying to overwrite the web.config after the transform was complete. Adding a Sleep task (from MSBuildCommunityTasks) after the MSBuild task took care of that issue.

I only tested this approach using the built in ASP.NET server, not IIS, so YMMV but I feel like this is a workable solution.

The FirstRun idea came from this post.

like image 164
rsbarro Avatar answered Nov 02 '22 06:11

rsbarro