开发者

How do I do Web.config Transformations with Visual Studio Website Projects?

开发者 https://www.devze.com 2023-02-12 11:31 出处:网络
It doesn\'t seem to be possible to change the Build Configuration of Visual Studio 2010 Website Projects (as opposed to Visual Studio Web Applications), and changing the Build C开发者_C百科onfiguratio

It doesn't seem to be possible to change the Build Configuration of Visual Studio 2010 Website Projects (as opposed to Visual Studio Web Applications), and changing the Build C开发者_C百科onfiguration is a key part of enabling Web.config transformations (it's not possible to change the configuration to anything except Debug).

How do I get Web.config transformations to work with Visual Studio 2010 Website projects if it's not possible to change the Build Configuration?


I'd prefer not to use entire an Web Application Project solution out of box. My solution is to use the XmlTransform task defined in Microsoft.Web.Publishing.Tasks.dll directly (this task is the core of WebConfigTransformation) This way it is flexible enough and does exactly what you expect it to do. For example here is the WebSiteTransformator.csproj I'm using for transforming web.config.

Here also is an example of flexibility that is impossible to reach with original WebConfigTransformation: it takes web.Template.config, applies web.$(Configuration).config over it and writes web.config. This allows us to add web.config itself into ignore list in source control. It is still valid csproj to be referenced by website:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <SchemaVersion>2.0</SchemaVersion>
    <OutputType>Library</OutputType>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    <OutputPath>$(TEMP)\TransformWebConfig\bin</OutputPath>
    <BaseIntermediateOutputPath>$(TEMP)\TransformWebConfig\obj\</BaseIntermediateOutputPath>
    <IntermediateOutputPath>$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
    <WebFolderName>$(SolutionDir)\MyWebSite\</WebFolderName>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="Dummy.cs" />
  </ItemGroup>
  <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll"/>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <Target Name="BeforeBuild">
    <TransformXml Source="$(WebFolderName)Web.Template.config"
                  Transform="$(WebFolderName)Web.$(Configuration).config"
                  Destination="$(WebFolderName)Web.config" />
  </Target>
</Project>


I found a pretty good blog post describing a solution to this here: http://andrewtwest.com/2010/02/25/using-web-config-transformations-in-web-site-projects/

In short: create an empty project (as long as it is not another website project) in your solution that contains the website. The empty project will give you access to msbuild through its project file, which will allow you to perform transforms on your website web.config.


I used a slightly alternative approach. Still a bit of a hack, but I think a lot more straightforward. This worked for me, but obviously there are a lot of different configurations available so I can't guarantee it'll work for everyone. This revolves around the way that a website is first packaged up in to your AppData folder before being published...

  1. Manually add a Web.Release.config file to the website and add the necessary transforms - obviously there's no 'Add Config Transform' option for websites, hence having to do this manually. Example Web.Release.config:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
        <appSettings>
            <add key="MySetting" value="NewValue" xdt:Transform="Replace" xdt:Locator="Match(key)" />
        </appSettings>
        <system.web>
            <compilation xdt:Transform="RemoveAttributes(debug)" />
        </system.web>
    </configuration>
    
  2. Inside the website.publishproj file, ensure the configuration is set to Release:

    <Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
    
  3. Add the following to the very bottom of website.publishproj (just before </Project>):

    <Target Name="AfterBuild">
      <MakeDir Directories="$(PackageArchiveRootDir)\..\CSAutoParameterize\original" />
      <TransformXml Source="Web.config" Transform="Web.$(ConfigurationName).config" Destination="$(PackageArchiveRootDir)\..\CSAutoParameterize\original\Web.config" StackTrace="false" />
    </Target>
    


Create a publish profile in VS 2017 and then right click on the .pubxml profile in App_Data\PublishProfiles and select Add Config Transform.

See https://social.msdn.microsoft.com/Forums/vstudio/en-US/31f41991-abb2-41de-ad0b-c1379cc7c806/vs-2013-express-for-web-webconfig-transforms?forum=visualstudiogeneral&prof=required


As mentioned in Andriy's comment above, Solution wide build events definitely seems like a cleaner way to do this.

I am adding this as a separate answer, as it gets a little lost in the comment, but IMHO is the best answer. Props to Andriy K and Sayed Ibrahim.


If you would prefer not to need a Web.Template.config, I used this:

<PropertyGroup>
    <_tempSourceFile>$([System.IO.Path]::GetTempFileName())</_tempSourceFile>
    <_tempTransformFile>$([System.IO.Path]::GetTempFileName())</_tempTransformFile>
</PropertyGroup>

<Copy SourceFiles="$(ProjectDir)Web.config" DestinationFiles="$(_tempSourceFile)"/>
<Copy SourceFiles="$(ProjectDir)Web.$(Configuration).config" DestinationFiles="$(_tempTransformFile)"/>

<TransformXml Source="$(_tempSourceFile)"
              Transform="$(_tempTransformFile)"
              Destination="$(ProjectDir)Web.config"
              StackTrace="false" />

Adapted from an answer here.

0

精彩评论

暂无评论...
验证码 换一张
取 消