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

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

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

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

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

Ответы [ 9 ]

116 голосов
/ 07 августа 2008

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

System.Configuration.ConfigurationFileMap fileMap = new ConfigurationFileMap(strConfigPath); //Path to your config file
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
65 голосов
/ 10 января 2013

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

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

Ответ Ишмаэля, как правило, работает, однако я обнаружил одну проблему, которая заключается в том, что использование 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.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. Но, похоже, это работает для меня.

10 голосов
/ 08 августа 2008

В дополнение к ответу Измаила метод OpenMappedMachineConfiguration() всегда будет возвращать объект Configuration. Поэтому, чтобы проверить, загружен ли он, следует проверить свойство HasFile, где true означает, что оно получено из файла.

4 голосов
/ 11 ноября 2010

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

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

string sMsg = System.Configuration.ConfigurationManager.AppSettings["WSURL"];
2 голосов
/ 19 марта 2019

Принят неправильный ответ !!

Вызывает следующее исключение при доступе к свойству 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);
1 голос
/ 15 июля 2014

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

var config = WebConfigurationManager.OpenWebConfiguration("~/Sites/" + requestDomain + "/");
(..)
config.AppSettings.Settings["xxxx"].Value;
0 голосов
/ 09 августа 2018

Это должно сработать:

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

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

0 голосов
/ 09 февраля 2016

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

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

// can call root.Elements(...)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...