Я разрабатываю компонент доступа к данным, который будет использоваться на сайте, содержащем смесь классических ASP и ASP.NET страниц, и мне нужен хороший способ управления его конфигурационными настройками.
Я хотел бы использовать пользовательский ConfigurationSection
, и для страниц ASP.NET это отлично работает. Но когда компонент вызывается через COM interop со страницы классического ASP, компонент не работает в контексте запроса ASP.NET и поэтому не имеет представления о web.config.
Есть ли способ сказать ConfigurationManager
, чтобы он просто загружал конфигурацию из произвольного пути (например, ...\web.config
, если моя сборка находится в папке /bin
)? Если да, то я думаю, что мой компонент сможет вернуться к этому пути, если стандартный ConfigurationManager.GetSection
вернет null
для моей пользовательской секции.
Любые другие подходы к этому будут приветствоваться!
Попробуйте это:
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' возражают, чтобы перезагрузить его назад к it' s исходное состояние. С этим решение, Вы можете сохранить временную конфигурацию приложения рассмотренной:
using(AppConfig.Change(tempFileName))
{
// tempFileName is used for the app config during this context
}
Ответ Ishmaeel'a в целом работает, однако я обнаружил одну проблему, которая заключается в том, что использование OpenMappedMachineConfiguration
, похоже, теряет унаследованные группы секций из machine.config. Это означает, что вы можете получить доступ к своим собственным пользовательским секциям (а это все, что хотел ОП), но не к обычным системным секциям. Например, этот код не будет работать:
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. Но, похоже, это работает для меня.
В дополнение к ответу Измаила, метод OpenMappedMachineConfiguration()
всегда возвращает объект Configuration
. Поэтому, чтобы проверить, загрузился ли он, нужно проверить свойство HasFile
, где true означает, что он пришел из файла.
Принятый ответ неправильный!!
Это бросает следующее исключение на доступ к собственности AppSettings:
Неспособный бросить объект типа ' Система. Конфигурация. DefaultSection' напечатать ' Система. Конфигурация. AppSettingsSection'.
Вот правильное решение:
System.Configuration.ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = "YourFilePath";
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
Я обеспечил, ценности конфигурации к слову приняли .nET Compoent следующим образом.
A. ЧИСТЫЙ компонент Библиотеки классов быть назвал/принял в MS Word. Обеспечить конфигурацию оценивает моему компоненту, я создал winword.exe.config в C:\Program Files\Microsoft Office\OFFICE11 folder. Вам необходимо читать, ценности конфигураций как Вы делают в Традиционном.NET.
string sMsg = System.Configuration.ConfigurationManager.AppSettings["WSURL"];
Поскольку ASP.NET используют WebConfigurationManager:
var config = WebConfigurationManager.OpenWebConfiguration("~/Sites/" + requestDomain + "/");
(..)
config.AppSettings.Settings["xxxx"].Value;
Это должно добиться цели:
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "newAppConfig.config);
Источник: https://www.codeproject.com/Articles/616065/Why-Where-and-How-of-NET-Configuration-Files