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

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

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

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

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

7.08.2008 14:07:21
Ohad Schneider 6.07.2011 16:19:15
9 ОТВЕТОВ
РЕШЕНИЕ

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

System.Configuration.ConfigurationFileMap fileMap = new ConfigurationFileMap(strConfigPath); //Path to your config file
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
123
7.08.2008 14:14:44
Как программно получить значение strConfigPath для приложения ASP.NET WebForms, размещенного в sub.domain.com/virtualDir2, и путь C: \ Portals \ App1 \ v2 и файл конфигурации в C: \ Portals \ App1 \ v2 \ web.config ?
Kiquenet 7.10.2015 10:16:58
@Kiquenet: Суть вопроса в том, что strConfigPath является произвольным местом. Другими словами, вы решаете, какой путь, вместо того, чтобы полагаться на среду, чтобы попытаться загрузить файл конфигурации из его обычного расположения. Я предполагаю, что Server.MapPath даст вам абсолютное местоположение для любых файлов в вашем решении.
Ishmaeel 7.10.2015 10:32:07
Возможноvar config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~/web.config");
Kiquenet 7.10.2015 11:01:23
@Kiquenet Определенно.
Ucho 19.02.2020 13:36:39

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

10
23.04.2014 09:14:57

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

40
29.09.2010 02:52:01
Вы также можете использовать перегрузку ConfigurationManager.OpenExeConfiguration (String) для той же цели. См .: codeproject.com/KB/dotnet/mysteriesofconfiguration3.aspx#t2_1
Ohad Schneider 6.07.2011 16:00:07

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

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

string sMsg = System.Configuration.ConfigurationManager.AppSettings["WSURL"];
4
22.07.2011 09:27:08

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

Я считаю, что это лучшее решение для загрузки файла конфигурации с нетривиальным путем, особенно лучший способ прикрепить файл конфигурации к 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
}
66
23.05.2017 11:54:50
Это также работает для загрузки файлов web.config. Я использую его для загрузки web.config вместо app.config для консольного приложения, связанного с задачей. ;)
James Wilkins 16.03.2015 17:48:04
Это (и другие ответы здесь) не работает для меня. Я добавил код в program.cs - функция: Main (). Моя конфигурация содержит перенаправление версии сборки (см. Stackoverflow.com/questions/30165393/… ), но перенаправление не влияет при изменении конфигурации вручную.
Vortex852456 11.05.2015 15:20:35
Вы использовали "APP_CONFIG_FILE"?
Saturn Technologies 12.05.2015 07:14:18

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

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

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

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

// can call root.Elements(...)
0
8.02.2016 22:18:57

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

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

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

0
9.08.2018 10:53:32

Принятый ответ неверен !!

Выдает следующее исключение при доступе к свойству 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);
7
19.03.2019 13:12:05
да, это определенно правильный ответ! Спасибо за публикацию вашего ответа.
Fabio Milheiro 17.06.2019 15:40:52
Я думаю, что System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration еще более корректен, но он не доступен для .NET Core, поэтому в этом случае, кажется, этот ответ завершен.
Risord 8.10.2019 12:03:29