Использование ConfigurationManager для загрузки конфигурации из произвольного местоположения

Я разрабатываю компонент доступа к данным, который будет использоваться на веб-сайте, содержащем смесь классических ASP и ASP.NET страниц, и нужен хороший способ управления его настройками конфигурации.

Я хотел бы использовать пользовательский ConfigurationSection, и для ASP.NET страницы это отлично работает. Но когда компонент вызывается через COM-взаимодействие с классической страницы ASP, компонент не выполняется в контексте ASP.NET запрос и, следовательно, не имеет знаний о web.конфиг.

Is есть способ сказать ConfigurationManager чтобы просто загрузить конфигурацию из произвольного пути (например,..web.config Если моя сборка в )? Если есть, то я думаю, что мой компонент может вернуться к этому, если по умолчанию ConfigurationManager.GetSection возвращает null для моего пользовательского раздела.

любые другие подходы к этому будут приветствоваться!

8 ответов


попробуйте это:

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

другое решение-переопределить настройки по умолчанию путь к файлу.

Я считаю это лучшим решением для загрузки файла конфигурации нетривиального пути, в частности, лучший способ прикрепить файл конфигурации к 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
}

ответ Ishmaeel обычно работает, однако я нашел одну проблему, которая заключается в том, что использование OpenMappedMachineConfiguration кажется, потерять унаследованные группы разделов от машины.конфиг. Это означает, что вы можете получить доступ к своим собственным пользовательским разделам (это все, что требуется 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, так что это в значительной степени недоступно по обычным каналам.

есть два способа, которые я нашел, чтобы обойти это. Первый, который мне не нравится,-это повторно реализовать группы разделов системы, скопировав их с машины.конфигурации в собственный веб.конфигурации, например,

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

Я не уверен, что само веб-приложение будет работать правильно после этого, но вы можете получить доступ к sectionGroups правильно.

второе решение вместо этого, чтобы открыть свой веб.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!

я осмелюсь сказать, что ни один из ответов, представленных здесь, ни мой, ни Ишмаэля, не используют эти функции так, как предполагали разработчики .NET. Но, кажется, это работает для меня.


В дополнение к ответу Ishmaeel, метода OpenMappedMachineConfiguration() всегда будет возвращать


Я предоставил значения конфигурации Word hosted .nET Compoent следующим образом.

компонент библиотеки классов .NET вызывается / размещается в MS Word. Чтобы предоставить значения конфигурации моему компоненту, я создал winword.исполняемый.config в C:\Program папка Files\Microsoft Office\OFFICE11. Вы должны иметь возможность читать значения конфигураций, как в традиционном .Сеть.

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

для ASP.NET используйте WebConfigurationManager:

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

использовать обработку XML:

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

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

это должно сделать трюк:

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

источник: https://www.codeproject.com/Articles/616065/Why-Where-and-How-of-NET-Configuration-Files