Использование ConfigurationManager для загрузки конфигурации из произвольного места
Я разрабатываю компонент доступа к данным, который будет использоваться на веб-сайте, который содержит сочетание классических страниц ASP и ASP.NET, и мне нужен хороший способ управления его параметрами конфигурации.
Я хотел бы использовать обычай ConfigurationSection
, и для страниц ASP.NET это отлично работает. Но когда компонент вызывается через COM-взаимодействие с классической страницы ASP, компонент не работает в контексте запроса ASP.NET и, следовательно, не знает web.config.
Есть ли способ указать ConfigurationManager
просто загрузить конфигурацию с произвольного пути (например, ..\web.config
если моя сборка находится в /bin
папке)? Если есть, то я думаю, что мой компонент может вернуться к этому, если для моего настраиваемого раздела ConfigurationManager.GetSection
вернется значение по умолчанию null
.
Приветствуются любые другие подходы к этому!
Ответов (9)9
Другое решение - переопределить путь к файлу конфигурации среды по умолчанию.
Я считаю, что это лучшее решение для загрузки файла конфигурации нетривиального пути, в частности лучший способ прикрепить файл конфигурации к 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
}
Это должно помочь:
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "newAppConfig.config);
Источник: https://www.codeproject.com/Articles/616065/Why-Where-and-How-of-NET-Configuration-Files
Принятый ответ неверен !!
Он вызывает следующее исключение при доступе к свойству 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);
Ответ 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. Но, похоже, это работает для меня.
Я предоставил значения конфигурации для Word hosted .nET Compoent следующим образом.
Компонент библиотеки классов .NET вызывается / размещается в MS Word. Чтобы предоставить значения конфигурации моему компоненту, я создал файл winword.exe.config в папке C: \ Program Files \ Microsoft Office \ OFFICE11. Вы должны уметь читать значения конфигурации, как в традиционном .NET.
string sMsg = System.Configuration.ConfigurationManager.AppSettings["WSURL"];