NET 配置(app.config/web.config/setings.sets)

我有一个。NET 应用程序,该应用程序具有用于调试和发布版本的不同配置文件。例如,debug app.config 文件指向启用了调试的开发 SQL Server,而发布目标指向活动的 SQL Server。还有其他一些设置,其中一些在调试/发布中是不同的。

我目前使用两个单独的配置文件(debug. app.config 和 release. app.config)。我在这个项目上有一个构建事件,它说如果这是一个发布构建,那么将 release ase.app.config 复制到 app.config,否则将 debug. app.config 复制到 app.config。

问题是这个应用程序似乎是从 setings.sets 文件中获取它的设置,所以我必须在 Visual Studio 中打开 setings.sets,然后它会提示我设置已经更改,所以我接受这些更改,保存 setings.sets,并且必须重新构建以使它使用正确的设置。

是否有更好的/推荐的/首选的方法达到类似的效果?或者同样地,我的方法是否完全错误,是否有更好的方法?

91468 次浏览

我当前的雇主首先将 dev 级别(debug、 stage、 live 等)放到 machine.config 文件中,从而解决了这个问题。然后他们编写代码来获取并使用正确的配置文件。这解决了应用程序部署后出现错误连接字符串的问题。

他们最近编写了一个中央 Web 服务,该服务从 machine.config 值中的值返回正确的连接字符串。

这是最好的解决办法吗? 也许不是,但对他们有效。

在我看来,你似乎可以从 VisualStudio2005Web 部署项目s 中受益。

这样,您就可以告诉它根据构建配置更新/修改 web.config 文件的各个部分。

看一下 这篇来自 Scott Gu 的博客文章快速概述/示例。

这里有一个相关的问题:

改进您的构建过程

配置文件提供了一种覆盖设置的方法:

<appSettings file="Local.config">

不需要签入两个(或更多)文件,只需签入默认的配置文件,然后在每台目标机器上放置 Local.config,只需放置 appSettings 部分,该部分重写了该特定机器。

如果使用配置节,则等效为:

configSource="Local.config"

当然,从其他机器上备份所有 Local.config 文件并将它们签入到某个地方是个好主意,但不要作为实际解决方案的一部分。每个开发人员在 Local.config 文件上放置一个“忽略”,这样它就不会被签入,从而覆盖其他所有人的文件。

(实际上你不必称它为“ Local.config”,我就是这么用的)

从我正在阅读的内容来看,似乎您正在使用 VisualStudio 进行构建过程。你有没有想过改用 MSBuild 和 南特

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>

使用 WebDeploymentProject 是一个很好的解决方案。 我的站点中有2/3不同的 web.config 文件,在发布时,这取决于所选择的配置模式(release/stage/等等。.)我会在网上复制。Config 并在 AfterBuild 事件中将其重命名为 Web.config,然后删除我不需要的内容(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>

我们过去常常使用 WebDeployment 项目,但是现在已经迁移到了 NAnt。我们当前没有对不同的设置文件进行分支和复制,而是将配置值直接嵌入到构建脚本中,并通过 xmlpok 任务将其注入到配置文件中:

  <xmlpoke
file="${stagingTarget}/web.config"
xpath="/configuration/system.web/compilation/@debug"
value="true"
/>

无论哪种情况,您的配置文件都可以具有您想要的任何开发人员值,并且它们在您的开发环境中工作得很好,而不会破坏您的生产系统。我们发现开发人员在测试时不太可能随意更改构建脚本变量,所以偶然的错误配置比我们尝试过的其他技术更少见,尽管仍然有必要在过程的早期添加每个变量,这样开发人员的值就不会在默认情况下被推动。

您将在这里找到另一种解决方案: 在 ASP.NET 中在 Development/UAT/Prod 环境之间切换配置的最佳方式?,它使用 XSLT 转换 web.config。

还有一些关于使用 NAnt 的好例子。

任何在不同环境中可能存在差异的配置都应该存储在 机器水平中,而不是 应用程度.(更多关于配置级别的信息。)

这些是我通常存储在机器级别的配置元素:

当每个环境(开发人员、集成、测试、阶段、活动)在 C: Windows Microsoft.NET Framework64 v2.0.50727 CONFIG目录中有自己独特的设置时,您可以在不同环境之间推广 应用程序代码,而不需要在构建后进行任何修改。

显然,机器级 CONFIG 目录的内容在不同的存储库或不同的文件夹结构中得到版本控制。你可以。配置文件更加源代码控制友好,通过智能使用 ConfigSource

我已经做了7年,在超过25家不同公司的200多个 ASP.NET 应用程序上。(不是吹牛,只是想让你知道,我从来没有见过这种方法 没有工作的情况。)

和您一样,我也设置了‘ multi’app.config-eg app.configDEV、 app.configTEST、 app.config.LOCAL。我看到了一些很好的建议,但如果你喜欢它的工作方式,我会添加以下内容:

我有一个
<appSettings>
<add key = "Env" value = "[Local] "/> 对于每个应用程序,我都会在标题栏的用户界面中添加以下内容: 来自 ConfigurationManager.AppSettings 获取(“ Env”) ;

我只是将配置重命名为我的目标(我有一个项目,有8个应用程序,有很多数据库/wcf 配置对应4个事件)。要部署与点击一次到每个我改变4个会议在项目和去。(我喜欢自动化)

我唯一的问题是要记住在更改后“清除所有”,因为旧的配置在手动重命名后“卡住”了。(我认为这将解决你设置。设置问题)。

我发现这个工作得非常好(有一天我会有时间查看 MSBuild/NAnt)

我们的项目也有同样的问题,我们必须维护 dev、 qa、 uat 和 prod 的配置。下面是我们遵循的原则(只适用于熟悉 MSBuild 的用户) :

在 MSBuildCommunity 任务扩展插件中使用 MSBuild。它包括“ XmlMassUpdate”任务,一旦您给它正确的节点开始,它可以“大量更新”任何 XML 文件中的条目。

实施方法:

1)您需要有一个配置文件,其中包含 dev env 条目; 这是解决方案中的配置文件。

2)您需要有一个“ Substittions.xml”文件,该文件只包含针对每个环境的 DIFFERENT (大部分是 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>

将「 $Environment 」替换为「 QA 」或「 Prod 」。你正在建造的。注意,您应该处理配置文件的副本,而不是实际的配置文件本身,以避免任何可能的不可恢复错误。

只需运行构建文件,然后将更新后的配置文件移动到部署环境,就可以完成了!

为了更好地了解情况,请阅读以下内容:

Http://blogs.microsoft.co.il/blogs/dorony/archive/2008/01/18/easy-configuration-deployment-with-msbuild-and-the-xmlmassupdate-task.aspx

这可能有助于一些人处理 Settings.sets 和 App.config: 在 Visual Studio (在我的例子中是 Visual Studio 2008)中编辑 Settings.sets 网格中的任何值时,注意属性窗格中的 GenerateDefaultValueInCode 属性。

如果将 GenerateDefaultValueInCode 设置为 True (这里默认为 True!),默认值被编译成 EXE (或 DLL) ,当您在纯文本编辑器中打开它时,您可以发现它嵌入在文件中。

我正在处理一个控制台应用,如果我在 EXE 中缺省,应用程序总是忽略放在同一个目录中的配置文件!真是个噩梦,整个互联网上都没有这方面的信息。

上面说的是 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
}
}

返回文章页面 Web.config:

当您希望将应用程序托管在 IIS 上时,需要 Web.config。Config 是 IIS 的一个强制配置文件,用于配置它在 Kestrel 面前作为反向代理的行为。如果要在 IIS 上托管 web.config,则必须维护它。

应用程序设置 json:

对于与 IIS 无关的其他所有内容,可以使用 AppSeting.json。 Json 用于 ASP。网络核心托管。NET Core 使用“ ASPNETCORE _ ENVIRONMENT”环境变量来确定当前环境。默认情况下,如果您运行应用程序而没有设置这个值,它将自动默认为 Product 环境,并使用“ AppSetting.Production.json”文件。当您通过 Visual Studio 进行调试时,它将环境设置为 Development,因此它使用“ AppSetting.json”。你可浏览此网页了解如何在视窗设定宿主环境变量。

App.config:

Config 是用户使用的另一个配置文件。NET,主要用于 Windows 窗体、 Windows 服务、控制台应用程序和 WPF 应用程序。当你开始你的 Asp。通过控制台应用 app.config 托管的 Net Core 也被使用。


DR

配置文件的选择由您为服务选择的宿主环境决定。如果使用 IIS 托管服务,请使用 Web.config 文件。如果您正在使用任何其他托管环境,请使用 App.config 文件。 参见 使用配置文件配置服务文档 也可以查看 ASP.NET Core 中的 Configuration。