C# .NET 配置 (app.config/web.config/settings.settings)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/132544/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
.NET Configuration (app.config/web.config/settings.settings)
提问by Gavin
I have a .NET application which has different configuration files for Debug and Release builds. E.g. the debug app.config file points to a development SQL Serverwhich has debugging enabled and the release target points to the live SQL Server. There are also other settings, some of which are different in debug/release.
我有一个 .NET 应用程序,它具有用于调试和发布版本的不同配置文件。例如,调试 app.config 文件指向已启用调试的开发SQL Server,发布目标指向实时 SQL Server。还有其他设置,其中一些在调试/发布中有所不同。
I currently use two separate configuration files (debug.app.config and release.app.config). I have a build event on the project which says if this is a release build then copy release.app.config to app.config, else copy debug.app.config to app.config.
我目前使用两个单独的配置文件(debug.app.config 和 release.app.config)。我在项目上有一个构建事件,它表示如果这是一个发布版本,则将 release.app.config 复制到 app.config,否则将 debug.app.config 复制到 app.config。
The problem is that the application seems to get its settings from the settings.settings file, so I have to open settings.settings in Visual Studio which then prompts me that the settings have changed so I accept the changes, save settings.settings and have to rebuild to make it use the correct settings.
问题是该应用程序似乎从 settings.settings 文件中获取其设置,因此我必须在 Visual Studio 中打开 settings.settings,然后提示我设置已更改,因此我接受更改,保存 settings.settings 并重建以使其使用正确的设置。
Is there a better/recommended/preferred method for achieving a similar effect? Or equally, have I approached this completely wrong and is there a better approach?
有没有更好/推荐/首选的方法来达到类似的效果?或者同样,我是否完全错误地处理了这个问题,有没有更好的方法?
回答by Hector Sosa Jr
My current employer solved this issue by first putting the dev level (debug, stage, live, etc) in the machine.config file. Then they wrote code to pick that up and use the right config file. That solved the issue with the wrong connection string after the app gets deployed.
我现在的雇主通过首先将开发级别(调试、阶段、实时等)放在 machine.config 文件中解决了这个问题。然后他们编写了代码来获取并使用正确的配置文件。这解决了应用程序部署后连接字符串错误的问题。
They just recently wrote a central webservice that sends back the correct connection string from the value in the machine.config value.
他们最近编写了一个中央 Web 服务,该服务从 machine.config 值中的值发回正确的连接字符串。
Is this the best solution? Probably not, but it works for them.
这是最好的解决方案吗?可能不是,但它对他们有用。
回答by Magnus Johansson
To me it seems that you can benefit from the Visual Studio 2005 Web Deployment Projects.
对我来说,您似乎可以从Visual Studio 2005 Web 部署项目中受益。
With that, you can tell it to update/modify sections of your web.config file depending on the build configuration.
有了它,您可以告诉它根据构建配置更新/修改 web.config 文件的部分。
Take a look at this blog entry from Scott Gufor a quick overview/sample.
查看来自 Scott Gu 的这篇博客条目,以获取快速概述/示例。
回答by Eric Z Beard
There is a related question here:
这里有一个相关的问题:
Config files come with a way to override the settings:
配置文件附带了一种覆盖设置的方法:
<appSettings file="Local.config">
Instead of checking in two files (or more), you only check in the default config file, and then on each target machine, you put a Local.config, with just the appSettings section that has the overrides for that particular machine.
而不是签入两个文件(或更多),你只签入默认的配置文件,然后在每台目标机器上,你放置一个 Local.config,只有 appSettings 部分具有该特定机器的覆盖。
If you are using config sections, the equivalent is:
如果您使用配置部分,则等效为:
configSource="Local.config"
Of course, it's a good idea to make backup copies of all the Local.config files from other machines and check them in somewhere, but not as a part of the actual solutions. Each developer puts an "ignore" on the Local.config file so it doesn't get checked in, which would overwrite everyone else's file.
当然,从其他机器制作所有 Local.config 文件的备份副本并在某处检查它们是一个好主意,但不是作为实际解决方案的一部分。每个开发人员都会在 Local.config 文件上放置一个“忽略”,这样它就不会被签入,这会覆盖其他所有人的文件。
(You don't actually have to call it "Local.config", that's just what I use)
(您实际上不必将其称为“Local.config”,这正是我使用的)
回答by Steven Williams
From what I am reading, it sounds like you are using Visual Studio for your build process. Have you thought about using MSBuild and Nantinstead?
从我读到的内容来看,听起来您正在使用 Visual Studio 进行构建过程。你有没有想过改用 MSBuild 和Nant?
Nant's xml syntax is a little weird but once you understand it, doing what you mentioned becomes pretty trivial.
Nant 的 xml 语法有点奇怪,但是一旦你理解了它,做你提到的事情就变得很简单了。
<target name="build">
<property name="config.type" value="Release" />
<msbuild project="${filename}" target="Build" verbose="true" failonerror="true">
<property name="Configuration" value="${config.type}" />
</msbuild>
<if test="${config.type == 'Debug'}">
<copy file=${debug.app.config}" tofile="${app.config}" />
</if>
<if test="${config.type == 'Release'}">
<copy file=${release.app.config}" tofile="${app.config}" />
</if>
</target>
回答by Adam Vigh
One of the solutions that worked me fine was using a WebDeploymentProject. I had 2/3 different web.config files in my site, and on publish, depending on the selected configuration mode (release/staging/etc...) I would copy over the Web.Release.config and rename it to web.config in the AfterBuild event, and delete the ones I don't need (Web.Staging.config for example).
对我有用的解决方案之一是使用 WebDeploymentProject。我的站点中有 2/3 个不同的 web.config 文件,在发布时,根据所选的配置模式(发布/暂存/等...),我将复制 Web.Release.config 并将其重命名为 web.config。 config 在 AfterBuild 事件中,并删除我不需要的那些(例如 Web.Staging.config)。
<Target Name="AfterBuild">
<!--Web.config -->
<Copy Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " SourceFiles="$(SourceWebPhysicalPath)\Web.Release.config" DestinationFiles="$(OutputPath)\Web.config" />
<Copy Condition=" '$(Configuration)|$(Platform)' == 'Staging|AnyCPU' " SourceFiles="$(SourceWebPhysicalPath)\Web.Staging.config" DestinationFiles="$(OutputPath)\Web.config" />
<!--Delete extra files -->
<Delete Files="$(OutputPath)\Web.Release.config" />
<Delete Files="$(OutputPath)\Web.Staging.config" />
<Delete Files="@(ProjFiles)" />
</Target>
回答by jasondoucette
We used to use Web Deployment projects but have since migrated to NAnt. Instead of branching and copying different setting files we currently embed the configuration values directly in the build script and inject them into our config files via xmlpoke tasks:
我们曾经使用过 Web 部署项目,但后来迁移到了 NAnt。我们目前将配置值直接嵌入到构建脚本中,并通过 xmlpoke 任务将它们注入到我们的配置文件中,而不是分支和复制不同的设置文件:
<xmlpoke
file="${stagingTarget}/web.config"
xpath="/configuration/system.web/compilation/@debug"
value="true"
/>
In either case, your config files can have whatever developer values you want and they'll work fine from within your dev environment without breaking your production systems. We've found that developers are less likely to arbitrarily change the build script variables when testing things out, so accidental misconfigurations have been rarer than with other techniques we've tried, though it's still necessary to add each var early in the process so that the dev value doesn't get pushed to prod by default.
在任何一种情况下,您的配置文件都可以具有您想要的任何开发人员值,并且它们可以在您的开发环境中正常工作而不会破坏您的生产系统。我们发现开发人员在测试时不太可能随意更改构建脚本变量,因此与我们尝试过的其他技术相比,意外配置错误的情况更罕见,尽管仍然有必要在流程的早期添加每个变量,以便默认情况下,不会将 dev 值推送到 prod。
回答by Aaron Powell
You'll find another solution here: Best way to switch configuration between Development/UAT/Prod environments in ASP.NET?which uses XSLT to transfor the web.config.
您将在此处找到另一个解决方案:在 ASP.NET 中的开发/UAT/Prod 环境之间切换配置的最佳方法?它使用 XSLT 转换 web.config。
There are also some good examples on using NAnt.
还有一些关于使用 NAnt 的好例子。
回答by Portman
Any configuration that might differ across environments should be stored at the machine level, not the application level. (More info on configuration levels.)
任何可能因环境而异的配置都应该存储在机器级别,而不是应用程序级别。(有关配置级别的更多信息。)
These are the kinds of configuration elements that I typically store at the machine level:
这些是我通常存储在机器级别的配置元素类型:
- Application settings
- Connection strings
- retail=true
- Smtp settings
- Health monitoring
- Hosting environment
- Machine key
When each environment (developer, integration, test, stage, live) has its own unique settings in the c:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIGdirectory, then you can promote your application codebetween environments without any post-build modifications.
当每个环境(开发者、集成、测试、阶段、现场)在c:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIG目录中都有自己独特的设置时,那么您就可以在环境之间推广您的应用程序代码,而无需任何构建后修改。
And obviously, the contents of the machine-level CONFIG directory get version-controlled in a different repository or a different folder structure from your app. You can make your .config files more source-control friendly through intelligent use of configSource.
很明显,机器级 CONFIG 目录的内容在不同的存储库或与您的应用程序不同的文件夹结构中受到版本控制。您可以通过智能使用configSource使您的 .config 文件对源代码控制更加友好。
I've been doing this for 7 years, on over 200 ASP.NET applications at 25+ different companies. (Not trying to brag, just want to let you know that I've never seen a situation where this approach doesn'twork.)
我已经这样做了 7 年,在 25 多家不同公司的 200 多个 ASP.NET 应用程序上。(不是想吹嘘,只是想让您知道我从未见过这种方法不起作用的情况。)
回答by Tony Trembath-Drake
Like you I've also set up 'multi' app.config - eg app.configDEV, app.configTEST, app.config.LOCAL. I see some of the excellent alternatives suggested, but if you like the way it works for you, I'd add the following:
像你一样,我也设置了“多”app.config - 例如 app.configDEV、app.configTEST、app.config.LOCAL。我看到了一些出色的替代方案,但如果您喜欢它适合您的方式,我会添加以下内容:
I have a <appSettings>
<add key = "Env" value = "[Local] "/>
for each app I add this to the UI in the titlebar:
from ConfigurationManager.AppSettings.Get("Env");
我将<appSettings>
<add key = "Env" value = "[Local] "/>
每个应用程序添加到标题栏中的 UI 中: from ConfigurationManager.AppSettings.Get("Env");
I just rename the config to the one I'm targetting (I have a project with 8 apps with lots of database/wcf config against 4 evenioments). To deploy with clickonce into each I change 4 seetings in the project and go. (this I'd love to automate)
我只是将配置重命名为我要定位的配置(我有一个包含 8 个应用程序的项目,其中包含针对 4 个事件的大量数据库/wcf 配置)。要使用 clickonce 部署到每个项目中,我更改了项目中的 4 个设置然后开始。(这我很想自动化)
My only gotcha is to remember to 'clean all' after a change, as the old config is 'stuck' after a manual rename. (Which I think WILL fix you setting.setting issue).
我唯一的问题是记住在更改后“全部清除”,因为旧配置在手动重命名后“卡住”。(我认为这将解决您的设置。设置问题)。
I find this works really well (one day I'll get time to look at MSBuild/NAnt)
我发现这非常有效(总有一天我会花时间看看 MSBuild/NAnt)
回答by Punit Vora
Our project has the same issue where we had to maintain configs for dev, qa, uat and prod. Here is what we followed (only applies if you are familiar with MSBuild):
我们的项目有同样的问题,我们必须维护 dev、qa、uat 和 prod 的配置。这是我们遵循的内容(仅适用于熟悉 MSBuild 的情况):
Use MSBuild with the MSBuild Community tasks extension. It includes the 'XmlMassUpdate' task that can 'mass-update' entries in any XML file once you give it the correct node to start with.
将 MSBuild 与 MSBuild 社区任务扩展一起使用。它包括“XmlMassUpdate”任务,一旦你给它正确的节点开始,它就可以“大量更新”任何 XML 文件中的条目。
To Implement:
实施:
1) You need to have one config file which will have your dev env entries; this is the config file in your solution.
1) 您需要有一个配置文件,其中包含您的 dev env 条目;这是您的解决方案中的配置文件。
2) You need to have a 'Substitutions.xml' file, that contains only the entries that are DIFFERENT (appSettings and ConnectionStrings mostly) for each environment. Entries that do not change across the environment need not be put in this file. They can live in the web.config file of the solution and will not be touched by the task
2) 您需要有一个“Substitutions.xml”文件,其中仅包含每个环境的不同条目(主要是 appSettings 和 ConnectionStrings)。在整个环境中不会改变的条目不需要放在这个文件中。它们可以存在于解决方案的 web.config 文件中,并且不会被任务触及
3) In your build file, just call the XML mass update task and provide the right environment as a parameter.
3) 在您的构建文件中,只需调用 XML 批量更新任务并提供正确的环境作为参数。
See example below:
请参阅下面的示例:
<!-- Actual Config File -->
<appSettings>
<add key="ApplicationName" value="NameInDev"/>
<add key="ThisDoesNotChange" value="Do not put in substitution file" />
</appSettings>
<!-- Substitutions.xml -->
<configuration xmlns:xmu="urn:msbuildcommunitytasks-xmlmassupdate">
<substitutions>
<QA>
<appSettings>
<add xmu:key="key" key="ApplicationName" value="NameInQA"/>
</appSettings>
</QA>
<Prod>
<appSettings>
<add xmu:key="key" key="ApplicationName" value="NameInProd"/>
</appSettings>
</Prod>
</substitutions>
</configuration>
<!-- Build.xml file-->
<Target Name="UpdateConfigSections">
<XmlMassUpdate ContentFile="Path\of\copy\of\latest web.config" SubstitutionsFile="path\of\substitutionFile" ContentRoot="/configuration" SubstitutionsRoot="/configuration/substitutions/$(Environment)" />
</Target>
replace '$Environment' with 'QA' or 'Prod' based on what env. you are building for. Note that you should work on a copy of a config file and not the actual config file itself to avoid any possible non-recoverable mistakes.
根据环境将 '$Environment' 替换为 'QA' 或 'Prod'。你正在建设。请注意,您应该处理配置文件的副本,而不是实际的配置文件本身,以避免任何可能的不可恢复的错误。
Just run the build file and then move the updated config file to your deployment environment and you are done!
只需运行构建文件,然后将更新的配置文件移动到您的部署环境即可!
For a better overview, read this:
要获得更好的概述,请阅读以下内容: