38

I have a main Web.config file, and under that there is a Web.Test.config, Web.Development.Config etc.

When I preview the transformation via SlowCheetah on the Test config, it appears to transform the values correctly.

When I switch my build environment from Development to Testing and try to debug the application, the application runs under whatever values are in the main Web.config file (i.e. it is not transforming anything).

How do I make the build environment pick the correct config when debugging rather than just always using the base Web.config file? Is this possible?

3 Answers 3

66

You can transform Web.config on build. Add this target to *.csproj file:

<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\WebApplications\Microsoft.WebApplication.targets" />
<Target Name="BeforeBuild">
    <TransformXml 
        Source="Web.Base.config" 
        Transform="Web.$(Configuration).config" 
        Destination="Web.config" />
</Target>

Keep the origin configuration in Web.Base.config. It's enough to enable transformation and it works for any XML config file. SlowCheetah is no longer needed at all.

To avoid unwanted transform on publish, use this (and check the comments and the link below for more details):

From a reminder in the comments I realized that I also have a problem with Visual Studio transforming the XML twice, when Publishing a project. The solution to this is to add a Condition to the Target-tag like this:

<Target Name="BeforeBuild" Condition="'$(PublishProfileName)' == '' And '$(WebPublishProfileFile)' == ''">

http://sebnilsson.com/a5410281/asp-net-transform-web-config-with-debug-release-on-build/

Sign up to request clarification or add additional context in comments.

8 Comments

This is the most simple solution, I did it and it works great. But... there is always a but... I always get the "Debugging Not Enable" error when it is enable on Web.Base.config but my Web.config is empty at first time. By selecting "Modify the Web.config file to enable debugging" and clicking OK, it continues working fine. If Web.config has last run version with debugging enable it works fine. It seems that debug enable is checked before transformation.
This solution is working fine. But another draw back is, that anything that Visual Studio/NuGet/etc. changes in the web.config file, needs to be ported manually to the Web.Base.config file.
For anyone else working with multiple versions of VS, replacing my hardcoded value with $(VisualStudioVersion) worked for me
don't have to use base if you don't want to <Target Name="BeforeBuild"> <TransformXml Source="Web.config" Transform="Web.$(Configuration).config" Destination="Web.config" /> </Target>
per the link provided this should be updated to correct double transform issue. "UPDATE: From a reminder in the comments I realized that I also have a problem with Visual Studio transforming the XML twice, when Publishing a project. The solution to this is to add a Condition to the Target-tag like this: <Target Name="BeforeBuild" Condition="'$(PublishProfileName)' == '' And '$(WebPublishProfileFile)' == ''"> "
|
6

XML transformations will only be applied when you publish web apps and not during build.

This blog post details a work around using build settings.

3 Comments

I combined the above solution Target BeforeBuild and this one. Making use of <DependentUpon>Web.Base.config</DependentUpon>. Thanks!
@mike123 - Could you provide a more detailed explanation of how that looks like? Looks interesting. I managed to make this work with SlowCheetah using their nuget package for web.config files.
@arviman the csproj file needed changes in two places ` ... <None Include="Web.Base.config" /> <Content Include="Web.config" /> <None Include="Web.PROD.config"> <DependentUpon>Web.config</DependentUpon> </None> ... <Import Project="$(SlowCheetahTargets)" Condition="Exists('$(SlowCheetahTargets)')" Label="SlowCheetah" /> <Target Name="BeforeBuild" Condition="'$(PublishProfileName)' == '' And '$(WebPublishProfileFile)' == ''"> <TransformXml Source="Web.Base.config" Transform="Web.$(Configuration).config" Destination="Web.config" /> </Target> </Project>`
0

The solution I applied was:

At application startup (ex: Global.asax), change the configuration file path with the following code snippet:

var oldConfigPath = (string) AppDomain.CurrentDomain.GetData("APP_CONFIG_FILE");
var directory = Directory.GetParent(oldConfigPath).FullName;

//Check if is using Web.config in source directory
if (Directory.GetFiles(directory).Any(s => s.EndsWith(".csproj")))
{                
   //Modify config file that must be used
   var path = $"{Assembly.GetExecutingAssembly().CodeBase}.config";
   AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", path);

   //Reset ConfigManager
   typeof(ConfigurationManager)
   .GetField("s_initState", BindingFlags.Static | BindingFlags.NonPublic)
   .SetValue(null, 0);

}

1 Comment

Is is a really hacky workaround to a poorly understood problem and is, in general, really bad advice.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.