Использование ConfigurationManager для загрузки конфигурации из произвольного местоположения
Я разрабатываю компонент доступа к данным, который будет использоваться на веб-сайте, содержащем смесь классических ASP и ASP.NET страниц, и нужен хороший способ управления его настройками конфигурации.
Я хотел бы использовать пользовательский ConfigurationSection
, и для ASP.NET страницы это отлично работает. Но когда компонент вызывается через COM-взаимодействие с классической страницы ASP, компонент не выполняется в контексте ASP.NET запрос и, следовательно, не имеет знаний о web.конфиг.
Is есть способ сказать ConfigurationManager
чтобы просто загрузить конфигурацию из произвольного пути (например,..web.config
Если моя сборка в )? Если есть, то я думаю, что мой компонент может вернуться к этому, если по умолчанию ConfigurationManager.GetSection
возвращает null
для моего пользовательского раздела.
любые другие подходы к этому будут приветствоваться!
8 ответов
попробуйте это:
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
объект, чтобы сбросить его обратно в его исходное состояние. С этим
решение, вы можете сохранить временную конфигурацию приложения в области:
using(AppConfig.Change(tempFileName))
{
// tempFileName is used for the app config during this context
}
ответ Ishmaeel обычно работает, однако я нашел одну проблему, которая заключается в том, что использование OpenMappedMachineConfiguration
кажется, потерять унаследованные группы разделов от машины.конфиг. Это означает, что вы можете получить доступ к своим собственным пользовательским разделам (это все, что требуется 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, так что это в значительной степени недоступно по обычным каналам.
есть два способа, которые я нашел, чтобы обойти это. Первый, который мне не нравится,-это повторно реализовать группы разделов системы, скопировав их с машины.конфигурации в собственный веб.конфигурации, например,
<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 правильно.
второе решение вместо этого, чтобы открыть свой веб.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.исполняемый.config в C:\Program папка Files\Microsoft Office\OFFICE11. Вы должны иметь возможность читать значения конфигураций, как в традиционном .Сеть.
string sMsg = System.Configuration.ConfigurationManager.AppSettings["WSURL"];
для ASP.NET используйте WebConfigurationManager:
var config = WebConfigurationManager.OpenWebConfiguration("~/Sites/" + requestDomain + "/");
(..)
config.AppSettings.Settings["xxxx"].Value;
использовать обработку XML:
var appPath = AppDomain.CurrentDomain.BaseDirectory;
var configPath = Path.Combine(appPath, baseFileName);;
var root = XElement.Load(configPath);
// can call root.Elements(...)
это должно сделать трюк:
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "newAppConfig.config);
источник: https://www.codeproject.com/Articles/616065/Why-Where-and-How-of-NET-Configuration-Files