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

时间:2008-08-07 14:07:21

标签: asp.net configuration asp-classic

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

我想使用自定义ConfigurationSection,对于ASP.NET页面,这非常有效。但是,当通过COM interop从经典ASP页面调用组件时,该组件不会在ASP.NET请求的上下文中运行,因此不了解web.config。

有没有办法告诉ConfigurationManager只是从任意路径加载配置(例如..\web.config如果我的程序集在/bin文件夹中)?如果有,那么我认为如果默认ConfigurationManager.GetSection为我的自定义部分返回null,我的组件可以回退到该状态。

欢迎任何其他方法!

9 个答案:

答案 0 :(得分:116)

试试这个:

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

答案 1 :(得分:65)

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

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

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

示例:

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

可在this blog找到更多详细信息。

此外,this other answer有一个很好的解决方案,包括要刷新的代码 应用程序配置和IDisposable对象将其重置为原始状态。有了这个 解决方案,您可以保留临时应用程序配置范围:

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

答案 2 :(得分:39)

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设计者的意图。但是,这似乎对我有用。

答案 3 :(得分:10)

除了Ishmaeel的回答之外,方法OpenMappedMachineConfiguration()将始终返回Configuration个对象。因此,要检查它是否已加载,您应该检查HasFile属性,其中true表示它来自文件。

答案 4 :(得分:4)

我为单词托管.nET Compoent提供了配置值,如下所示。

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

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

答案 5 :(得分:2)

接受的答案是错误的!

在访问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);

答案 6 :(得分:1)

对于ASP.NET使用WebConfigurationManager:

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

答案 7 :(得分:0)

使用XML处理:

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

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

答案 8 :(得分:0)

这应该可以解决问题:

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "newAppConfig.config);

来源:https://www.codeproject.com/Articles/616065/Why-Where-and-How-of-NET-Configuration-Files