问题
部署项目时,常常需要根据不同的环境使用不同的配置文件。例如,在部署网站时可能希望禁用调试选项,并更改连接字符串以使其指向不同的数据库。在创建 Web 项目时,Visual Studio 自动生成了 Web.config
、Web.Debug.config
、Web.release.config
这3个不同的配置文件,并提供了转换工具,用于在部署项目时自动转换配置文件内容。具体可以参考这2篇文章:如何:在部署 Web 应用程序项目时转换 Web.config 和 用于 Web 应用程序项目部署的 Web.config 转换语法 。
然而在其他项目类型中(如控制台应用程序、Windows 服务),并没有现成的配置文件的转换功能。
临时解决方案
准备2个配置文件:App.config
和 App.Release.config
,然后修改项目 .csproj
文件,更新 AfterBuild
生成事件:
<Target Name="AfterBuild" Condition="'$(Configuration)' == 'Release' "><Delete Files="$(TargetDir)$(TargetFileName).config" /><Copy SourceFiles="$(ProjectDir)\app.$(Configuration).config" DestinationFiles="$(TargetDir)$(TargetFileName).config" />
</Target>
|
这样在选择 Release 配置时,执行生成操作会删除 App.config
文件,然后用 App.Release.config
文件替换。虽然这样也可以实现根据环境来选择配置文件,但是这种方法需要保证这2个配置文件内容保持同步,特别是要保证 assemblyBinding 标签内容一致, 这个标签的作用是程序集版本重定向,如果不一致会抛出 “未能加载文件或程序集” 这个异常。
直到找到这篇文章 Enable app.debug.config app.release.config 时才完美解决配置文件转换的问题。
正式做法
- 我们在项目中添加
App.config
、App.Debug.config
、App.Release.config
这3个配置文件。 - 打开项目所在目录,用记事本或其他文本编辑器打开
.csproj
文件。 -
在 PropertyGroup
标签下添加如下内容:
<PropertyGroup><ProjectConfigFileName>App.config</ProjectConfigFileName>
</PropertyGroup>
|
-
在 ItemGroup
标签中找到和 App.config
、App.Debug.config
、App.Release.config
相关的项目,替换为
<None Include="App.config" />
<None Include="App.Debug.config"><DependentUpon>App.config</DependentUpon>
</None>
<None Include="App.Release.config"><DependentUpon>App.config</DependentUpon>
</None>
|
-
在最后一个 Import
标签后面添加:
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets" />
|
-
在 Import
标签后面添加 Target
标签:
<Target Name="AfterBuild"><TransformXml Source="@(AppConfigWithTargetPath)" Transform="$(ProjectConfigTransformFileName)" Destination="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')" />
</Target>
|
-
切换到 Visual Studio , 重新加载项目。
这时查看 Visual Studio 可以看到 App.config
的组织方式和 Web.config
一样了。
App.config
现在就可以使用 用于 Web 应用程序项目部署的 Web.config 转换语法 这篇文章中提到的转换语法了。
例如需要替换 connectionStrings
, App.config
有如下配置:
<?xml version="1.0" encoding="utf-8" ?>
<configuration><connectionStrings><add name="connString" connectionString="Server=debug;Database=test;Uid=root;Pwd=123456;CharSet=utf8;"providerName="MySql.Data.MySqlClient" /></connectionStrings>
</configuration>
|
只需要修改 App.Release.config
为如下内容即可:
<?xml version="1.0" encoding="utf-8"?><!-- 有关使用 web.config 转换的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkId=125889 --><configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"><connectionStrings><add name="connString"connectionString="Server=release;Database=test;Uid=root;Pwd=654321;CharSet=utf8;"xdt:Transform="SetAttributes" xdt:Locator="Match(name)" /></connectionStrings>
</configuration>
|
这样在选择 Release
配置时,connectionStrings
会自动替换成 App.Release.config
中的值。查看 bin\Release
目录下的 config 文件可以进行验证。
完整代码
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"><Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /><PropertyGroup><Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration><Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform><ProjectGuid>{8196CA4E-AD25-4F90-BB80-D27512BF4BD4}</ProjectGuid><OutputType>Exe</OutputType><AppDesignerFolder>Properties</AppDesignerFolder><RootNamespace>App.Config转换</RootNamespace><AssemblyName>App.Config转换</AssemblyName><TargetFrameworkVersion>v4.0</TargetFrameworkVersion><FileAlignment>512</FileAlignment></PropertyGroup><PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "><PlatformTarget>AnyCPU</PlatformTarget><DebugSymbols>true</DebugSymbols><DebugType>full</DebugType><Optimize>false</Optimize><OutputPath>bin\Debug\</OutputPath><DefineConstants>DEBUG;TRACE</DefineConstants><ErrorReport>prompt</ErrorReport><WarningLevel>4</WarningLevel></PropertyGroup><PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "><PlatformTarget>AnyCPU</PlatformTarget><DebugType>pdbonly</DebugType><Optimize>true</Optimize><OutputPath>bin\Release\</OutputPath><DefineConstants>TRACE</DefineConstants><ErrorReport>prompt</ErrorReport><WarningLevel>4</WarningLevel></PropertyGroup><PropertyGroup><ProjectConfigFileName>App.config</ProjectConfigFileName></PropertyGroup><ItemGroup><Reference Include="System" /><Reference Include="System.configuration" /><Reference Include="System.Core" /><Reference Include="System.Xml.Linq" /><Reference Include="System.Data.DataSetExtensions" /><Reference Include="Microsoft.CSharp" /><Reference Include="System.Data" /><Reference Include="System.Xml" /></ItemGroup><ItemGroup><Compile Include="Program.cs" /><Compile Include="Properties\AssemblyInfo.cs" /></ItemGroup><ItemGroup><None Include="App.config" /><None Include="App.Debug.config"><DependentUpon>App.config</DependentUpon></None><None Include="App.Release.config"><DependentUpon>App.config</DependentUpon><SubType>Designer</SubType></None></ItemGroup><Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /><Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets" /><!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets.<Target Name="BeforeBuild"></Target><Target Name="AfterBuild"></Target>--><Target Name="AfterBuild"><TransformXml Source="@(AppConfigWithTargetPath)" Transform="$(ProjectConfigTransformFileName)" Destination="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')" /></Target>
</Project>
|
示例项目下载:
App.Config转换.zip
参考链接
如何:在部署 Web 应用程序项目时转换 Web.config
用于 Web 应用程序项目部署的 Web.config 转换语法
Enable app.debug.config app.release.config