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

时间:2020-03-05 18:38:20  来源:igfitidea点击:

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

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

有没有办法告诉ConfigurationManager只是从任意路径(例如,如果我的程序集位于/ bin文件夹中,则加载.. \ web.config)吗?如果有的话,我想我的组件可以回到默认的ConfigurationManager.GetSection为我的自定义部分返回null的情况。

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

解决方案

回答

试试这个:

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

回答

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

回答

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设计人员的意图使用这些功能。但是,这似乎对我有用。

回答

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

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

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