我有有不同的配置文件用于调试和发布版本.NET应用程序。 例如调试app.config文件指向一个发展的SQL Server具有调试启用,并公布目标指向活的SQL Server。 也有其他的设置,其中一些是在调试/版本不同。
我目前使用两个单独的配置文件(debug.app.config和release.app.config)。 我对项目的生成事件,说,如果这是一个发布版本然后复制release.app.config到的app.config,否则复制debug.app.config到的app.config。
问题是,应用程序似乎从settings.settings文件中获取它的设置,所以我必须要打开Visual Studio中,然后提示我的设置已经改变,所以我接受更改settings.settings,保存settings.settings和有重建,使其使用正确的设置。
有没有更好的/推荐/首选实现类似的效果的方法? 或者同样,有我走近这个完全错误的,有没有更好的方法吗?
Answer 1:
可能不同的不同环境中的任何配置应该存储在机器的水平 ,而不是应用程序级别 。 (上配置级别的更多信息。)
这些是在我通常在机器级存储配置元素:
- 应用程序设置
- 连接字符串
- 零售=真
- SMTP设置
- 健康监测
- 托管环境
- 机键
当每个环境(开发,集成,测试,阶段,生活)具有在C自己独特的设定:\ WINDOWS \ Microsoft.NET \ Framework64 \ V2.0.50727 \ CONFIG目录中,那么你就可以促进环境之间的应用程序代码没有任何生成后的修改。
很显然,在机器级别CONFIG目录中的内容得到不同的版本库或者从您的应用程序不同的文件夹结构,版本控制。 你可以让你的.config文件更多的源代码控制通过智能使用友好configSource 。
我已经做了7年,在上25+不同的公司超过200 ASP.NET应用程序。 (不是要炫耀,只是想让你知道,我从来没有见过的情况下这种做法是行不通的。)
Answer 2:
这可能帮助一些人应对Settings.settings和App.config中:注意在属性面板中GenerateDefaultValueInCode属性而(在我的情况的Visual Studio 2008)编辑任何在Visual Studio中的Settings.settings格的值。
如果设置GenerateDefaultValueInCode为True(真在这里默认的!),默认值被编译成EXE文件(或DLL),你可以找到它在文件中内嵌当你在一个纯文本编辑器打开它。
我工作在一个控制台应用程序,如果我在EXE有默认值,应用程序总是被忽略在同一目录下的配置文件的地方! 相当一个恶梦,这个整个互联网上的任何信息。
Answer 3:
这里有一个相关的问题:
提高构建过程
配置文件拿出一个办法来覆盖这些设置:
<appSettings file="Local.config">
相反,在两个文件(或更多)检查,只检查默认的配置文件,然后将每个目标机器上,你把Local.config,只有拥有该特定机器覆盖appSettings部分。
如果您使用的配置部分,相当于是:
configSource="Local.config"
当然,这是一个好主意,以从其他机器的所有Local.config文件的备份副本,并检查他们在某个地方,但不是实际的解决方案的一部分。 每个开发人员提出了“忽略”的Local.config文件,因此它不会签入,这将覆盖其他人的文件。
(你实际上并没有把它称作“Local.config”,这是我用正是)
Answer 4:
从我读什么,它听起来就像你正在使用Visual Studio为您的构建过程。 你有没有想过使用的MSBuild和南特呢?
楠的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>
Answer 5:
对我来说,似乎可以从受益的Visual Studio 2005 Web部署项目秒。
就这样,你可以告诉它更新/修改取决于构建配置你的web.config文件的部分。
看看从斯科特谷这篇博客的快速浏览/样品。
Answer 6:
我们以前使用的Web部署项目,但此后迁移到楠。 相反,分支和复制不同的设置文件,我们目前在构建脚本直接嵌入配置值,并通过xmlpoke任务,其注入我们的配置文件:
<xmlpoke
file="${stagingTarget}/web.config"
xpath="/configuration/system.web/compilation/@debug"
value="true"
/>
在这两种情况下,你的配置文件可以有你想要的任何开发价值,他们会不会破坏你的生产系统工作从你的开发环境中的罚款。 我们发现,开发商不太可能测试的东西出来时,任意改变构建脚本变量,因此意外的错误配置已经比我们尝试其他技术少见,但它仍然需要在这个过程中,使早期添加的每个变种dev的值不被推默认督促。
Answer 7:
我现在的雇主首先投入machine.config文件dev的水平(调试,舞台,现场等)解决了这个问题。 然后,他们编写代码来挑选和使用正确的配置文件。 这解决了问题,与错误的连接字符串的应用进行了部署后。
他们只是最近写了,从在machine.config值值发送回正确的连接字符串中央web服务。
这是最好的解决办法吗? 或许不会,但它为他们工作。
Answer 8:
一说我工作罚款使用WebDeploymentProject的解决方案。 我有2/3不同的web.config文件在我的网站,并在发布,根据所选的配置模式(发行/舞台/等...)我会复制在Web.Release.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>
Answer 9:
您会在这里找到另一种解决办法: 切换在ASP.NET开发/ UAT /生产环境之间的配置最佳方式吗? 它使用XSLT transfor web.config中。
也有使用楠一些很好的例子。
Answer 10:
我们凸出有,我们不得不保持dev的,质量保证,UAT和PROD CONFIGS同样的问题。 这里是我们遵循的(只有在你熟悉的MSBuild):
使用的MSBuild用的MSBuild社区任务扩展。 它包括在任何XML文件可以“大规模更新”项,一旦你给它正确的节点开始与“XmlMassUpdate”任务。
要实现:
1)你需要有这将有你的dev的包膜输入一个配置文件; 这是您的解决方案配置文件。
2)你需要有一个“Substitutions.xml”文件,即仅包含不同(每个环境的appSettings和的ConnectionStrings居多)的条目。 不跨环境变化的条目不必在此文件中。 他们可以住在该解决方案的web.config文件,将不会被任务感动
3)在你的构建文件,只需调用XML大规模更新任务,并提供合适的环境作为参数。
见下面例子:
<!-- 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>
基于什么ENV“QA”或“PROD”取代“$环境”。 你正在为。 请注意,您应该在一个配置文件的副本工作,而不是实际的配置文件本身,以避免任何可能的不可恢复的错误。
只要运行构建文件,然后将更新配置文件移动到您的部署环境和你做!
为了更好地概述,请阅读本:
http://blogs.microsoft.co.il/blogs/dorony/archive/2008/01/18/easy-configuration-deployment-with-msbuild-and-the-xmlmassupdate-task.aspx
Answer 11:
和你一样我也已经设置“多”的app.config - 例如app.configDEV,app.configTEST,app.config.LOCAL。 我看到一些很好的替代的建议,但如果你喜欢它适合你的方式,我想补充以下内容:
我有一个
<appSettings>
<add key = "Env" value = "[Local] "/>
每个应用我在标题栏添加此到UI:从ConfigurationManager.AppSettings.Get(’包膜蛋白”);
我刚刚重命名配置到一个我靶向(我已经有8个应用程序,有很多针对4个evenioments数据库/ WCF配置的项目)。 要使用ClickOnce部署到每个更改的项目4个seetings去。 (这个我喜欢自动化)
我唯一的疑难杂症是更改后rememeber以“干净所有”,作为手动重命名后的旧的配置是“卡住”。 (我认为这将解决你setting.setting问题)。
我觉得这个作品真的很好(有一天我会得到时间去看看的MSBuild /南特)
Answer 12:
它说asp.net以上,为什么不能在数据库中保存设置并使用自定义缓存来检索他们?
我们做到了在这里的原因是因为它更容易(我们)比它是获得许可,不断更新生产文件更新不断数据库。
自定义缓存的例子:
public enum ConfigurationSection
{
AppSettings
}
public static class Utility
{
#region "Common.Configuration.Configurations"
private static Cache cache = System.Web.HttpRuntime.Cache;
public static String GetAppSetting(String key)
{
return GetConfigurationValue(ConfigurationSection.AppSettings, key);
}
public static String GetConfigurationValue(ConfigurationSection section, String key)
{
Configurations config = null;
if (!cache.TryGetItemFromCache<Configurations>(out config))
{
config = new Configurations();
config.List(SNCLavalin.US.Common.Enumerations.ConfigurationSection.AppSettings);
cache.AddToCache<Configurations>(config, DateTime.Now.AddMinutes(15));
}
var result = (from record in config
where record.Key == key
select record).FirstOrDefault();
return (result == null) ? null : result.Value;
}
#endregion
}
namespace Common.Configuration
{
public class Configurations : List<Configuration>
{
#region CONSTRUCTORS
public Configurations() : base()
{
initialize();
}
public Configurations(int capacity) : base(capacity)
{
initialize();
}
public Configurations(IEnumerable<Configuration> collection) : base(collection)
{
initialize();
}
#endregion
#region PROPERTIES & FIELDS
private Crud _crud; // Db-Access layer
#endregion
#region EVENTS
#endregion
#region METHODS
private void initialize()
{
_crud = new Crud(Utility.ConnectionName);
}
/// <summary>
/// Lists one-to-many records.
/// </summary>
public Configurations List(ConfigurationSection section)
{
using (DbCommand dbCommand = _crud.Db.GetStoredProcCommand("spa_LIST_MyConfiguration"))
{
_crud.Db.AddInParameter(dbCommand, "@Section", DbType.String, section.ToString());
_crud.List(dbCommand, PopulateFrom);
}
return this;
}
public void PopulateFrom(DataTable table)
{
this.Clear();
foreach (DataRow row in table.Rows)
{
Configuration instance = new Configuration();
instance.PopulateFrom(row);
this.Add(instance);
}
}
#endregion
}
public class Configuration
{
#region CONSTRUCTORS
public Configuration()
{
initialize();
}
#endregion
#region PROPERTIES & FIELDS
private Crud _crud;
public string Section { get; set; }
public string Key { get; set; }
public string Value { get; set; }
#endregion
#region EVENTS
#endregion
#region METHODS
private void initialize()
{
_crud = new Crud(Utility.ConnectionName);
Clear();
}
public void Clear()
{
this.Section = "";
this.Key = "";
this.Value = "";
}
public void PopulateFrom(DataRow row)
{
Clear();
this.Section = row["Section"].ToString();
this.Key = row["Key"].ToString();
this.Value = row["Value"].ToString();
}
#endregion
}
}
Answer 13:
Web.config文件:
当你想举办您的IIS应用程序需要Web.config文件。 Web.config文件是IIS的强制性配置文件来配置将如何表现为在红隼的前反向代理。 你如果要其托管在IIS保持一个web.config。
AppSetting.json:
对于一切不涉及IIS,你用AppSetting.json。 AppSetting.json用于Asp.Net核心托管。 ASP.NET核心使用“ASPNETCORE_ENVIRONMENT”环境变量来确定当前的环境。 默认情况下,如果你不设置这个值运行应用程序,它会自动默认为生产环境,并使用“AppSetting.production.json”文件。 当您通过Visual Studio中调试它集所以它使用“AppSetting.json”的环境中发展。 看到这个网站,以了解如何设置托管环境变量在Windows上。
App.config中:
App.config中是.NET使用另一个配置文件,该文件主要用于Windows窗体,Windows服务,控制台应用程序和WPF应用程序。 当您启动Asp.Net核心通过控制台应用程序的app.config托管也被使用。
TL; DR
配置文件的选择是由你选择该服务的主机环境确定的。 如果您使用的是IIS托管服务,使用Web.config文件。 如果你正在使用的任何其他托管环境中,使用App.config文件。 请参阅使用配置文件文档配置服务 ,并检查了在ASP.NET核心配置。
文章来源: .NET Configuration (app.config/web.config/settings.settings)