我正在开发一个数据访问组件,该组件将在包含经典ASP和ASP.NET页面混合的网站中使用,并且需要一种管理其配置设置的好方法。
我想使用自定义ConfigurationSection,对于ASP.NET页面,它的效果很好。 但是,当从经典ASP页面通过COM互操作调用该组件时,该组件未在ASP.NET请求的上下文中运行,因此不了解web.config。
有没有办法告诉ConfigurationManager从任意路径加载配置(例如,如果我的程序集位于/bin文件夹中,则是..\web.config)? 如果有的话,我想如果我的自定义部分的默认ConfigurationManager.GetSection返回null,我的组件可以回落到那个位置。
任何其他方法都将受到欢迎!
尝试这个:
1 2
| System.Configuration.ConfigurationFileMap fileMap = new ConfigurationFileMap(strConfigPath); //Path to your config file
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedMachineConfiguration(fileMap); |
另一个解决方案是覆盖默认环境配置文件路径。
我发现它是非平凡配置文件加载的最佳解决方案,尤其是将配置文件附加到dll的最佳方法。
1
| AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", <Full_Path_To_The_Configuration_File>); |
例:
1
| AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", @"C:\Shared\app.config"); |
可以在此博客中找到更多详细信息。
此外,此答案还有一个出色的解决方案,其中包含可刷新的代码
应用程序配置和IDisposable对象将其重置回其原始状态。有了这个
解决方案中,您可以将临时应用程序配置的范围设置为:
1 2 3 4
| using(AppConfig.Change(tempFileName))
{
// tempFileName is used for the app config during this context
} |
Ishmaeel的答案通常可以奏效,但是我发现了一个问题,即使用OpenMappedMachineConfiguration似乎丢失了您从machine.config继承的节组。这意味着您可以访问自己的自定义部分(所有OP都需要),但不能访问常规系统部分。例如,此代码将不起作用:
1 2 3
| 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中来重新实现系统部分组。
1 2 3 4 5
| <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配置打开,无论如何它可能更接近其预期功能:
1 2 3
| 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的答案外,方法OpenMappedMachineConfiguration()将始终返回Configuration对象。因此,要检查它是否已加载,您应该检查HasFile属性,其中true表示它来自文件。
接受的答案是错误的!
访问AppSettings属性时将引发以下异常:
Unable to cast object of type 'System.Configuration.DefaultSection' to type 'System.Configuration.AppSettingsSection'.
这是正确的解决方案:
1 2 3
| System.Configuration.ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename ="YourFilePath";
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None); |
我将字词托管的.nET组件的配置值提供如下。
在MS Word中调用/托管的.NET类库组件。为了给组件提供配置值,我在C: Program Files Microsoft Office OFFICE11文件夹中创建了winword.exe.config。您应该能够像在传统.NET中一样读取配置值。
1
| string sMsg = System.Configuration.ConfigurationManager.AppSettings["WSURL"]; |
对于ASP.NET,请使用WebConfigurationManager:
1 2 3
| var config = WebConfigurationManager.OpenWebConfiguration("~/Sites/" + requestDomain +"/");
(..)
config.AppSettings.Settings["xxxx"].Value; |
这应该可以解决问题:
1
| AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE","newAppConfig.config); |
来源:https://www.codeproject.com/Articles/616065/Why-Where-and-How-of-NET-Configuration-Files
使用XML处理:
1 2 3 4 5
| var appPath = AppDomain.CurrentDomain.BaseDirectory;
var configPath = Path.Combine(appPath, baseFileName);;
var root = XElement.Load(configPath);
// can call root.Elements(...) |