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

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

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

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

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


person Mike Powell    schedule 07.08.2008    source источник
comment
См. stackoverflow.com/questions/3912727/   -  person Ohad Schneider    schedule 06.07.2011


Ответы (9)


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

System.Configuration.ConfigurationFileMap fileMap = new ConfigurationFileMap(strConfigPath); //Path to your config file
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
person Ishmaeel    schedule 07.08.2008
comment
Как я могу получить значение программно strConfigPath для моего приложения ASP.NET WebForms, размещенного в sub.domain.com/virtualDir2 и путь C: \ Portals \ App1 \ v2 и файл конфигурации в C: \ Portals \ App1 \ v2 \ web.config? - person Kiquenet; 07.10.2015
comment
@Kiquenet: Суть вопроса в том, что strConfigPath - это произвольное местоположение. Другими словами, вы решаете, каков путь, вместо того, чтобы полагаться на фреймворк, пытаясь загрузить файл конфигурации из его обычного местоположения. Я бы предположил, что Server. MapPath предоставит вам абсолютное расположение любых файлов в вашем решении. - person Ishmaeel; 07.10.2015
comment
Может быть var config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~/web.config"); - person Kiquenet; 07.10.2015
comment
@Kiquenet Определенно. - person Ucho; 19.02.2020

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

Я считаю, что это лучшее решение для загрузки файла конфигурации нетривиального пути, в частности лучший способ прикрепить файл конфигурации к 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
}
person Saturn Technologies    schedule 09.01.2013
comment
Это также работает для загрузки файлов web.config. Я использую его для загрузки web.config вместо app.config для консольного приложения, связанного с задачами. ;) - person James Wilkins; 16.03.2015
comment
Этот (и другие ответы здесь) не работает для меня. Я добавил код в program.cs - function: Main (). Моя конфигурация содержит перенаправление версии сборки (см. stackoverflow.com/ questions / 30165393 /), но при изменении конфигурации вручную перенаправление не влияет. - person Vortex852456; 11.05.2015
comment
Вы использовали APP_CONFIG_FILE? - person Saturn Technologies; 12.05.2015
comment
Это очень чистое и простое в реализации решение, которое у меня сработало. - person Caspian Canuck; 15.04.2021

Ответ 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>

Я не уверен, что само веб-приложение после этого будет работать правильно, но вы можете правильно получить доступ к 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!

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

person Gavin    schedule 29.09.2010
comment
Вы также можете использовать перегрузку ConfigurationManager.OpenExeConfiguration (String) для той же цели. См .: codeproject.com/KB/dotnet/mysteriesofconfiguration3.aspx#t2_1 - person Ohad Schneider; 06.07.2011

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

person Joseph Daigle    schedule 08.08.2008

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

Он вызывает следующее исключение при доступе к свойству 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);
person Jacob    schedule 19.03.2019
comment
да, это однозначно правильный ответ! Спасибо, что разместили свой ответ. - person Fabio Milheiro; 17.06.2019
comment
Я думаю, что System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration еще более правильный, но он недоступен для .NET Core, поэтому в этом случае этот ответ, похоже, выполняет работу. - person Risord; 08.10.2019
comment
У нас это сработало, спасибо! - person melanie johnson; 15.06.2021

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

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

string sMsg = System.Configuration.ConfigurationManager.AppSettings["WSURL"];
person Iftikhar Ali    schedule 11.11.2010

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

var config = WebConfigurationManager.OpenWebConfiguration("~/Sites/" + requestDomain + "/");
(..)
config.AppSettings.Settings["xxxx"].Value;
person Javier Cañon    schedule 14.07.2014
comment
первый параметр OpenWebConfiguration - это просто путь (папка). Чтобы указать имя файла, вам нужен второй параметр - person Garr Godfrey; 17.11.2020

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

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

// can call root.Elements(...)
person JoelFan    schedule 08.02.2016

Это должно помочь:

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

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

person gatsby    schedule 09.08.2018