使用ConfigurationManager从任意位置加载配置


124

我正在开发一个数据访问组件,该组件将在包含经典ASP和ASP.NET页面混合的网站中使用,并且需要一种好的方法来管理其配置设置。

我想使用一个custom ConfigurationSection,对于ASP.NET页面,这很好用。但是,当从经典ASP页面通过COM互操作调用组件时,该组件未在ASP.NET请求的上下文中运行,因此不了解web.config。

有没有一种方法可以告诉ConfigurationManager用户仅从任意路径加载配置(例如,..\web.config如果我的程序集位于/bin文件夹中)?如果有的话,我想如果我的自定义部分ConfigurationManager.GetSection返回默认值null,我的组件可以恢复到原来的状态。

任何其他方法都将受到欢迎!


Answers:


124

试试这个:

System.Configuration.ConfigurationFileMap fileMap = new ConfigurationFileMap(strConfigPath); //Path to your config file
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedMachineConfiguration(fileMap);

我怎样才能获得编程 strConfigPath我的ASP.NET值的WebForms在托管应用sub.domain.com/virtualDir2和路径C:\门户\应用1 \ V2配置文件C:\门户\应用1 \ V2 \ web.config文件
Kiquenet

1
@Kiquenet:问题的关键是strConfigPath是一个任意位置。换句话说,可以确定路径是什么,而不是依靠框架来尝试从常规位置加载配置文件。我假设Server.MapPath将为您提供解决方案中任何文件的绝对位置。
Ishmaeel 2015年

1
也许var config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~/web.config");
Kiquenet

@Kiquenet绝对。
Ucho

66

另一个解决方案是覆盖默认环境配置文件路径。

我发现它是非平凡配置文件加载的最佳解决方案,特别是将配置文件附加到dll的最佳方法。

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", <Full_Path_To_The_Configuration_File>);

例:

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", @"C:\Shared\app.config");

可以在此博客中找到更多详细信息。

此外,其他答案还有一个很好的解决方案,其中包含刷新应用程序配置的代码以及将IDisposable其重置为原始状态的对象。使用此解决方案,您可以将临时应用程序配置的范围设置为:

using(AppConfig.Change(tempFileName))
{
    // tempFileName is used for the app config during this context
}

1
这也可以加载web.config文件。我使用它为任务相关的控制台应用程序加载web.config而不是app.config。;)
James Wilkins 2015年

1
这(和这里的其他答案)对我不起作用。我已经在program.cs中添加了代码-函数:Main()。我的配置包含程序集版本重定向(请参阅stackoverflow.com/questions/30165393/…),但是当手动更改配置时,重定向不会影响。
Vortex852456

1
您是否使用过“ APP_CONFIG_FILE”?
土星技术公司

40

Ishmaeel的答案通常可以奏效,但是我发现了一个问题,即使用OpenMappedMachineConfiguration似乎会丢失您从machine.config继承的节组。这意味着您可以访问自己的自定义部分(所有OP都需要),但不能访问常规系统部分。例如,此代码将不起作用:

ConfigurationFileMap fileMap = new ConfigurationFileMap(strConfigPath);
Configuration configuration = ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
MailSettingsSectionGroup thisMail = configuration.GetSectionGroup("system.net/mailSettings") as MailSettingsSectionGroup;  // returns null

基本上,如果您将手表放在上configuration.SectionGroups,则会看到system.net未注册为SectionGroup,因此通过常规渠道几乎无法访问它。

我发现有两种方法可以解决此问题。第一个,我不喜欢,是通过将它们从machine.config复制到您自己的web.config中来重新实现系统部分组。

<sectionGroup name="system.net" type="System.Net.Configuration.NetSectionGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
  <sectionGroup name="mailSettings" type="System.Net.Configuration.MailSettingsSectionGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <section name="smtp" type="System.Net.Configuration.SmtpSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  </sectionGroup>
</sectionGroup>

我不确定此后Web应用程序本身是否可以正常运行,但是您可以正确访问sectionGroups。

第二种解决方案是改为将您的web.config作为EXE配置打开,无论如何它可能更接近其预期功能:

ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap() { ExeConfigFilename = strConfigPath };
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
MailSettingsSectionGroup thisMail = configuration.GetSectionGroup("system.net/mailSettings") as MailSettingsSectionGroup;  // returns valid object!

我不敢说这里提供的答案,无论是我的还是Ishmaeel的,都没有完全按照.NET设计人员的意图使用这些功能。但是,这似乎对我有用。


1
您也可以出于相同的目的使用ConfigurationManager.OpenExeConfiguration(String)重载。请参阅:codeproject.com/KB/dotnet/mysteriesofconfiguration3.aspx#t2_1
Ohad Schneider

10

除了Ishmaeel的答案外,该方法OpenMappedMachineConfiguration()还将始终返回Configuration对象。因此,要检查它是否已加载,您应该检查HasFile属性true,这意味着该属性来自文件。


9

接受的答案是错误的!

访问AppSettings属性时将引发以下异常:

无法将类型为“ System.Configuration.DefaultSection”的对象转换为类型为“ System.Configuration.AppSettingsSection”的对象。

这是正确的解决方案:

System.Configuration.ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = "YourFilePath";
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

1
是的,这绝对是正确的答案!感谢您发布答案。
Fabio Milheiro

我认为System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration甚至更正确,但不适用于.NET Core,因此在这种情况下,此答案似乎可以完成工作。
Risord

4

我向字托管.nET组件提供了配置值,如下所示。

在MS Word中调用/托管的.NET类库组件。为了向组件提供配置值,我在C:\ Program Files \ Microsoft Office \ OFFICE11文件夹中创建了winword.exe.config。您应该能够像在传统.NET中一样读取配置值。

string sMsg = System.Configuration.ConfigurationManager.AppSettings["WSURL"];

1

对于ASP.NET,请使用WebConfigurationManager:

var config = WebConfigurationManager.OpenWebConfiguration("~/Sites/" + requestDomain + "/");
(..)
config.AppSettings.Settings["xxxx"].Value;

0

使用XML处理:

var appPath = AppDomain.CurrentDomain.BaseDirectory;
var configPath = Path.Combine(appPath, baseFileName);;
var root = XElement.Load(configPath);

// can call root.Elements(...)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.