Использование ConfigurationManager для загрузки конфигурации из произвольного местоположения
Я разрабатываю компонент доступа к данным, который будет использоваться на веб-сайте, который содержит сочетание классических страниц ASP и ASP.NET и должен иметь хороший способ управления настройками конфигурации.
Я бы хотел использовать пользовательский ConfigurationSection
, а для страниц ASP.NET это отлично работает. Но когда компонент вызывается через COM-взаимодействие с классической ASP-страницы, компонент не работает в контексте запроса ASP.NET и поэтому не знает о web.config.
Есть ли способ сообщить ConfigurationManager
просто загрузить конфигурацию с произвольного пути (например, ..\web.config
, если моя сборка находится в папке /bin
)? Если есть, то я думаю, что мой компонент может вернуться к этому, если по умолчанию ConfigurationManager.GetSection
возвращает null
для моего пользовательского раздела.
Любые другие подходы к этому будут приветствоваться!
Ответы
Ответ 1
Попробуйте следующее:
System.Configuration.ConfigurationFileMap fileMap = new ConfigurationFileMap(strConfigPath); //Path to your config file
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
Ответ 2
Другое решение - переопределить путь к файлу конфигурации среды по умолчанию.
Я нахожу это лучшим решением для загрузки файла конфигурации нетривиального пути, в частности, лучший способ подключить файл конфигурации к dll.
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", <Full_Path_To_The_Configuration_File>);
Пример:
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", @"C:\Shared\app.config");
Более подробную информацию можно найти на в этом блоге.
Кроме того, этот другой ответ имеет отличное решение, в комплекте с кодом для обновления
конфигурацию приложения и объект IDisposable
до reset обратно в исходное состояние. С этим
решение, вы можете сохранить временную конфигурацию приложения:
using(AppConfig.Change(tempFileName))
{
// tempFileName is used for the app config during this context
}
Ответ 3
Ответ 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>
Я не уверен, что после этого веб-приложение будет работать правильно, но вы можете получить доступ к разделам правильно.
Второе решение заключается в том, чтобы открыть ваш 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!
Я полагаю, что ни один из представленных здесь ответов, ни мой, ни Ishmaeel, не используют эти функции, как планировали разработчики .NET. Но, похоже, это работает для меня.
Ответ 4
В дополнение к ответу Ishmaeel метод OpenMappedMachineConfiguration()
всегда будет возвращать объект Configuration
. Поэтому, чтобы проверить, загружена ли она, вы должны проверить свойство HasFile
, где true означает, что оно было получено из файла.
Ответ 5
Я предоставил значения конфигурации для размещенного слова .nET Compoent следующим образом.
Компонент библиотеки .NET Class, который вызывается/размещается в MS Word. Чтобы предоставить значения конфигурации моему компоненту, я создал winword.exe.config в папке C:\Program Files\Microsoft Office\OFFICE11. Вы должны иметь возможность читать значения конфигураций, как вы делаете в традиционном .NET.
string sMsg = System.Configuration.ConfigurationManager.AppSettings["WSURL"];
Ответ 6
Для ASP.NET используйте WebConfigurationManager:
var config = WebConfigurationManager.OpenWebConfiguration("~/Sites/" + requestDomain + "/");
(..)
config.AppSettings.Settings["xxxx"].Value;
Ответ 7
Использовать обработку XML:
var appPath = AppDomain.CurrentDomain.BaseDirectory;
var configPath = Path.Combine(appPath, baseFileName);;
var root = XElement.Load(configPath);
// can call root.Elements(...)