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

发布于 2025-01-04 17:11:12 字数 465 浏览 0 评论 0 原文

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

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

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

欢迎任何其他方法!

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.

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.

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.

Any other approaches to this would be welcome!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

流星番茄 2025-01-11 17:11:12

试试这个:

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

Try this:

System.Configuration.ConfigurationFileMap fileMap = new ConfigurationFileMap(strConfigPath); //Path to your config file
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
只涨不跌 2025-01-11 17:11:12

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

我发现它是非平凡路径配置文件加载的最佳解决方案,特别是将配置文件附加到 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
}

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.

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:

using(AppConfig.Change(tempFileName))
{
    // tempFileName is used for the app config during this context
}
萌梦深 2025-01-11 17:11:12

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

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:

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.

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.

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

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

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.

神仙妹妹 2025-01-11 17:11:12

接受的答案是错误的!

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

The accepted answer is wrong!!

It throws the following exception on accessing the AppSettings property:

Unable to cast object of type 'System.Configuration.DefaultSection' to type 'System.Configuration.AppSettingsSection'.

Here is the correct solution:

System.Configuration.ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = "YourFilePath";
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
从此见与不见 2025-01-11 17:11:12

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

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.

新一帅帅 2025-01-11 17:11:12

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

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

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

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

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.

string sMsg = System.Configuration.ConfigurationManager.AppSettings["WSURL"];
我还不会笑 2025-01-11 17:11:12

对于 ASP.NET 使用 WebConfigurationManager:

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

For ASP.NET use WebConfigurationManager:

var config = WebConfigurationManager.OpenWebConfiguration("~/Sites/" + requestDomain + "/");
(..)
config.AppSettings.Settings["xxxx"].Value;
不再让梦枯萎 2025-01-11 17:11:12

这应该可以解决问题:

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

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

This should do the trick :

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

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

全部不再 2025-01-11 17:11:12

使用XML处理:

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

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

Use XML processing:

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

// can call root.Elements(...)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文