问题

部署项目时,常常需要根据不同的环境使用不同的配置文件。例如,在部署网站时可能希望禁用调试选项,并更改连接字符串以使其指向不同的数据库。在创建 Web 项目时,Visual Studio 自动生成了 Web.configWeb.Debug.configWeb.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 时才完美解决配置文件转换的问题。

正式做法

  1. 我们在项目中添加 App.configApp.Debug.configApp.Release.config 这3个配置文件。
  2. 打开项目所在目录,用记事本或其他文本编辑器打开 .csproj 文件。
  3. 在 PropertyGroup 标签下添加如下内容:

    <PropertyGroup>
    <ProjectConfigFileName>App.config</ProjectConfigFileName>
    </PropertyGroup>
  4. 在 ItemGroup 标签中找到和 App.configApp.Debug.configApp.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>
  5. 在最后一个 Import 标签后面添加:

    <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets" />
  6. 在 Import 标签后面添加 Target 标签:

    <Target Name="AfterBuild">
    <TransformXml Source="@(AppConfigWithTargetPath)" Transform="$(ProjectConfigTransformFileName)" Destination="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')" />
    </Target>
  7. 切换到 Visual Studio , 重新加载项目。

这时查看 Visual Studio 可以看到 App.config 的组织方式和 Web.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

(全文完)
 
转转:http://www.darrenfang.com/2016/01/transform-app-config-when-deploying-a-c-sharp-project/
 

在部署 C#项目时转换 App.config 配置文件的更多相关文章

  1. C#项目 App.config 配置文件不同使用环境配置

    问题 部署项目时,常常需要根据不同的环境使用不同的配置文件.例如,在部署网站时可能希望禁用调试选项,并更改连接字符串以使其指向不同的数据库.在创建 Web 项目时,Visual Studio 自动生成 ...

  2. C# 读写App.config配置文件

    一.C#项目中添加App.config配置文件 在控制台程序中,默认会有一个App.config配置文件,如果不小心删除掉,或者其他程序需要配置文件,可以通过添加得到. 添加步骤:右键项目名称,选择“ ...

  3. IIS7或者IIS7.5部署MVC项目时出现404错误

    IIS7或者IIS7.5部署MVC项目时出现404错误 服务器上需要安装Windows 补丁 kb980368  下载链接:http://support.microsoft.com/kb/980368

  4. idea部署tomcat项目时,在项目里打断点不能拦截

    以下内容都是基于我自己的项目(如未解决道友们的问题,请别介意) idea部署tomcat项目时,在项目里打断点不能拦截,工作中遇到的问题,记录一下(tomcat6) 当项目的以下内容配置完毕后,启动项 ...

  5. C# 读取app.config配置文件 节点键值,提示 "配置系统未能初始化" 错误的解决方案

    新建C#项目,在app.config中添加了appSettings项,运行时出现"配置系统未能初始化"的错误,MSDN里写到,如果配置文件中包含 configSections 元素 ...

  6. C# 读写App.config配置文件的方法

    我们经常会希望在程序中写入一些配置信息,例如版本号,以及数据库的连接字符串等.你可能知道在WinForm应用程序中可以利用Properties.Settings来进行类似的工作,但这些其实都利用了Ap ...

  7. 关于App.config配置文件

    今天在做复习的时候,突然发现自己无法读取配置文件中的数据库连接字符串,而且检查了半天也没找出原因,最后求助万能的度娘才得以解决—— 1.App.config配置文件在项目中添加后不要修改名称,否则会出 ...

  8. 读写App.config配置文件的方法

    我们经常会希望在程序中写入一些配置信息,例如版本号,以及数据库的连接字符串等.你可能知道在WinForm应用程序中可以利用Properties.Settings来进行类似的工作,但这些其实都利用了Ap ...

  9. 【Core】.NET Core中读取App.config配置文件

    1.项目中添加App.config文件 因为.NET Core的项目本质是控制台应用,所以ConfigurationManager的API会去默认读取app.config配置文件,而不是web.con ...

随机推荐

  1. Java8中HashMap扩容算法小计

    Java8的HashMap扩容过程主要就是集中在resize()方法中 final Node<K,V>[] resize() { // ...省略不重要的 } 其中,当HashMap扩容完 ...

  2. [Beta]Scrum Meeting#6

    github 本次会议项目由PM召开,时间为5月11日晚上10点30分 时长15分钟 任务表格 人员 昨日工作 下一步工作 木鬼 撰写博客整理文档 撰写博客整理文档 swoip 改进界面 为适应新功能 ...

  3. java SDK服务端推送 --极光推送(JPush)

    网址:https://blog.csdn.net/duyusean/article/details/86581475 消息推送在APP应用中越来越普遍,来记录一下项目中用到的一种推送方式,对于Andr ...

  4. Mesa: GeoReplicated, Near RealTime, Scalable Data Warehousing

    Mesa的定义并没有反映出他的特点,因为分布式,副本,高可用,他都是依赖google的其他基础设施完成的 他最大的特点是,和传统数仓比,可以做到near real-time的返回聚合的查询结果 算入实 ...

  5. Windows Server 2012 R2 卸载IE浏览器

    If you run any Windows Servers, you may run into a scenario where you want to remove access to Inter ...

  6. android为什么不允许新开启一个线程来更新UI,而是用handler来更新界面

    下面是快速创建一个新线程的方法: 第一种:直接创建子线程并启动      new Thread() {@Overridepublic void run() {     //这里写入子线程需要做的工作  ...

  7. 004 制作自己的Java镜像

    一:制作镜像 1.需要的知识 dockfile docker build Jpress : http://jpress.io/       开源免费的新媒体运营系统 2.下载jpress http:/ ...

  8. 华为交换机在Telnet登录下自动显示接口信息

    因为用console连接交换机,默认是自动显示接口信息的,比如down掉一个接口后,会自动弹出接口被down掉的信息,但是在telnet连接下,默认是不显示这些信息的,需要开启后才可显示. 1.首先开 ...

  9. linux命令详解之du命令

    du命令概述du命令作用是估计文件系统的磁盘已使用量,常用于查看文件或目录所占磁盘容量.du命令与df命令不同,df命令是统计磁盘使用情况,详见linux命令详解之df命令.du命令会直接到文件系统内 ...

  10. setTimeout的小尴尬

    我们都知道,alert这种内置弹框会阻塞后续代码执行: 之所以如此,就是因为JavaScript代码在浏览器中是单线程执行的.换句话说,浏览器中只有一个主线程负责运行所有JavaScript代码(不考 ...