2008-08-07 67 views
110

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

我想使用自定义ConfigurationSection,并且对于ASP.NET页面来说这很好。但是,当从传统的ASP页面通过COM interop调用该组件时,该组件不会在ASP.NET请求的上下文中运行,因此不了解web.config。

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

任何其他方法,这将是值得欢迎的!

+2

请访问http:// stackoverflow.com/questions/3912727/openmappedexeconfiguration-vs-openexeconfiguration/6599688#6599688 – 2011-07-06 16:19:15

回答

104

试试这个:

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

如何获取我的ASP.NET _WebForms_应用程序托管的_programmatically_ ** strConfigPath **值*** http://sub.domain.com/virtualDir2/***和路径*** C:\ Portals \ App1 \ v2 ***和_config file_在*** C:\ Portals \ App1 \ v2 \ web.config ***? – Kiquenet 2015-10-07 10:16:58

+0

@Kiquenet:问题的关键在于strConfigPath是一个_arbitrary_位置。换句话说,_you_决定什么是路径,而不是依赖框架来尝试从传统位置加载配置文件。我会假设[Server.MapPath](https://msdn.microsoft.com/en-us/library/system.web.httpserverutility.mappath(v = vs.110).aspx)会为您提供绝对位置解决方案中的文件。 – Ishmaeel 2015-10-07 10:32:07

+0

也许`var config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(“〜/ web.config”);` – Kiquenet 2015-10-07 11:01:23

9

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

37

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

4

我按如下方式向word托管的.nET Compoent提供了配置值。

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

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

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

我觉得它是非平凡路径配置文件加载的最佳解决方案,尤其是将配置文件附加到dll的最佳方式。

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

实施例:可在this blog找到

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

的更多细节。

此外,this other answer有一个很好的解决方案,其中包含代码以刷新 应用配置和IDisposable对象将其重置回原始状态。有了这个 解决方案,可以保持临时应用程序配置作用域:

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

对于ASP.NET使用WebConfigurationManager:

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

使用XML处理:

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

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