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

时间:2022-06-16 05:10:29

I'm developing a data access component that will be used in a website that contains a mix of classic ASP and ASP.NET pages, and need a good way to manage its configuration settings.

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

I'd like to use a custom ConfigurationSection, and for the ASP.NET pages this works great. But when the component is called via COM interop from a classic ASP page, the component isn't running in the context of an ASP.NET request and therefore has no knowledge of web.config.

我想使用定制的ConfigurationSection,以及ASP。这非常有用。但是,当从一个经典的ASP页面通过COM interop调用该组件时,该组件并没有在ASP上下文中运行。NET请求,因此不了解web.config。

Is there a way to tell the ConfigurationManager to just load the configuration from an arbitrary path (e.g. ..\web.config if my assembly is in the /bin folder)? If there is then I'm thinking my component can fall back to that if the default ConfigurationManager.GetSection returns null for my custom section.

是否有一种方法可以告诉ConfigurationManager从任意路径(例如.\web)加载配置。配置如果我的程序集在/bin文件夹中)?如果有的话,我认为我的组件可以回到默认的配置管理器。GetSection返回自定义部分的null。

Any other approaches to this would be welcome!

任何其他方法都是受欢迎的!

7 个解决方案

#1


108  

Try this:

试试这个:

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

#2


64  

Another solution is to override the default environment configuration file path.

另一个解决方案是重写默认的环境配置文件路径。

I find it the best solution for the of non-trivial-path configuration file load, specifically the best way to attach configuration file to dll.

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

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

Example:

例子:

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

More details may be found at this blog.

更多的细节可以在这个博客上找到。

Additionally, this other answer has an excellent solution, complete with code to refresh the app config and an IDisposable object to reset it back to it's original state. With this solution, you can keep the temporary app config scoped:

另外,这个解决方案有一个很好的解决方案,它包含了更新app配置的代码和一个IDisposable object以将其重置为原始状态。有了这个解决方案,您可以将临时应用程序配置限定在以下范围:

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

#3


38  

Ishmaeel's answer generally does work, however I found one issue, which is that using OpenMappedMachineConfiguration seems to lose your inherited section groups from machine.config. This means that you can access your own custom sections (which is all the OP wanted), but not the normal system sections. For example, this code will not work:

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

Basically, if you put a watch on the configuration.SectionGroups, you'll see that system.net is not registered as a SectionGroup, so it's pretty much inaccessible via the normal channels.

基本上,如果你把手表放在配置上。SectionGroups,你会看到system.net并没有注册为SectionGroup,所以它通过普通的通道是无法访问的。

There are two ways I found to work around this. The first, which I don't like, is to re-implement the system section groups by copying them from machine.config into your own web.config e.g.

我发现有两种方法可以解决这个问题。第一个,我不喜欢的,是通过从机器中复制系统节组来重新实现它们。配置到您自己的web。配置如。

<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>

I'm not sure the web application itself will run correctly after that, but you can access the sectionGroups correctly.

我不确定web应用程序本身在那之后是否会正确运行,但是您可以正确地访问sectionGroups。

The second solution it is instead to open your web.config as an EXE configuration, which is probably closer to its intended function anyway:

第二个解决方案是打开web。配置作为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!

I daresay none of the answers provided here, neither mine or Ishmaeel's, are quite using these functions how the .NET designers intended. But, this seems to work for me.

我敢说,这里提供的答案,无论是我的还是以实玛利的,都没有一个像。net设计者所期望的那样使用这些函数。但是,这似乎对我有用。

#4


9  

In addition to Ishmaeel's answer, the method OpenMappedMachineConfiguration() will always return a Configuration object. So to check to see if it loaded you should check the HasFile property where true means it came from a file.

除了Ishmaeel的答案之外,OpenMappedMachineConfiguration()方法始终返回一个配置对象。为了检查它是否被加载,你应该检查HasFile属性,true表示它来自一个文件。

#5


4  

I provided the configuration values to word hosted .nET Compoent as follows.

我向word托管的。net组合提供了配置值,如下所示。

A .NET Class Library component being called/hosted in MS Word. To provide configuration values to my component, I created winword.exe.config in C:\Program Files\Microsoft Office\OFFICE11 folder. You should be able to read configurations values like You do in Traditional .NET.

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

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

#6


1  

For ASP.NET use WebConfigurationManager:

ASP。净使用WebConfigurationManager:

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

#7


1  

Use XML processing:

使用XML处理:

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

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

#1


108  

Try this:

试试这个:

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

#2


64  

Another solution is to override the default environment configuration file path.

另一个解决方案是重写默认的环境配置文件路径。

I find it the best solution for the of non-trivial-path configuration file load, specifically the best way to attach configuration file to dll.

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

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

Example:

例子:

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

More details may be found at this blog.

更多的细节可以在这个博客上找到。

Additionally, this other answer has an excellent solution, complete with code to refresh the app config and an IDisposable object to reset it back to it's original state. With this solution, you can keep the temporary app config scoped:

另外,这个解决方案有一个很好的解决方案,它包含了更新app配置的代码和一个IDisposable object以将其重置为原始状态。有了这个解决方案,您可以将临时应用程序配置限定在以下范围:

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

#3


38  

Ishmaeel's answer generally does work, however I found one issue, which is that using OpenMappedMachineConfiguration seems to lose your inherited section groups from machine.config. This means that you can access your own custom sections (which is all the OP wanted), but not the normal system sections. For example, this code will not work:

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

Basically, if you put a watch on the configuration.SectionGroups, you'll see that system.net is not registered as a SectionGroup, so it's pretty much inaccessible via the normal channels.

基本上,如果你把手表放在配置上。SectionGroups,你会看到system.net并没有注册为SectionGroup,所以它通过普通的通道是无法访问的。

There are two ways I found to work around this. The first, which I don't like, is to re-implement the system section groups by copying them from machine.config into your own web.config e.g.

我发现有两种方法可以解决这个问题。第一个,我不喜欢的,是通过从机器中复制系统节组来重新实现它们。配置到您自己的web。配置如。

<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>

I'm not sure the web application itself will run correctly after that, but you can access the sectionGroups correctly.

我不确定web应用程序本身在那之后是否会正确运行,但是您可以正确地访问sectionGroups。

The second solution it is instead to open your web.config as an EXE configuration, which is probably closer to its intended function anyway:

第二个解决方案是打开web。配置作为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!

I daresay none of the answers provided here, neither mine or Ishmaeel's, are quite using these functions how the .NET designers intended. But, this seems to work for me.

我敢说,这里提供的答案,无论是我的还是以实玛利的,都没有一个像。net设计者所期望的那样使用这些函数。但是,这似乎对我有用。

#4


9  

In addition to Ishmaeel's answer, the method OpenMappedMachineConfiguration() will always return a Configuration object. So to check to see if it loaded you should check the HasFile property where true means it came from a file.

除了Ishmaeel的答案之外,OpenMappedMachineConfiguration()方法始终返回一个配置对象。为了检查它是否被加载,你应该检查HasFile属性,true表示它来自一个文件。

#5


4  

I provided the configuration values to word hosted .nET Compoent as follows.

我向word托管的。net组合提供了配置值,如下所示。

A .NET Class Library component being called/hosted in MS Word. To provide configuration values to my component, I created winword.exe.config in C:\Program Files\Microsoft Office\OFFICE11 folder. You should be able to read configurations values like You do in Traditional .NET.

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

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

#6


1  

For ASP.NET use WebConfigurationManager:

ASP。净使用WebConfigurationManager:

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

#7


1  

Use XML processing:

使用XML处理:

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

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