2008-08-07 13 views
110

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

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

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

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

+2

Смотреть Http: // stackoverflow.com/questions/3912727/openmappedexeconfiguration-vs-openexeconfiguration/6599688#6599688 – 2011-07-06 16:19:15

ответ

104

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

System.Configuration.ConfigurationFileMap fileMap = new ConfigurationFileMap(strConfigPath); //Path to your config file 
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedMachineConfiguration(fileMap); 
+0

Как я могу получить _programmatically_ ** значение strConfigPath ** для моего приложения ASP.NET _WebForms_, размещенного в *** http: //sub.domain.com/virtualDir2/*** и путь *** C: \ Portals \ App1 \ v2 *** и _config file_ в *** C: \ Portals \ App1 \ v2 \ web.config ***? – Kiquenet 2015-10-07 10:16:58

+0

@Kiquenet: Вопрос в том, что strConfigPath - это место _arbitrary_. Другими словами, вы определяете путь, а не полагаетесь на фреймворк, чтобы попытаться загрузить файл конфигурации из его обычного местоположения. Я бы предположил, что [Server.MapPath] (https://msdn.microsoft.com/en-us/library/system.web.httpserverutility.mappath (v = vs.110) .aspx) даст вам абсолютное местоположение для любого файлов в вашем решении. – Ishmaeel 2015-10-07 10:32:07

+0

Возможно, `var config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration (" ~/web.config ");` – Kiquenet 2015-10-07 11:01:23

9

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

37

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

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

4

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

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

string sMsg = System.Configuration.ConfigurationManager.AppSettings["WSURL"]; 
64

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

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

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", <Full_Path_To_The_Configuration_File>); 

Пример:

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", @"C:\Shared\app.config"); 

Более подробную информацию можно найти по адресу this blog.

Кроме того, this other answer имеет превосходное решение, в комплекте с кодом, чтобы обновить в приложение конфигурации и IDisposable объект, чтобы сбросить его обратно в исходное состояние. С помощью этого решения, вы можете сохранить временное приложение конфигурации области видимости:

using(AppConfig.Change(tempFileName)) 
{ 
    // tempFileName is used for the app config during this context 
} 
1

Для использования ASP.NET WebConfigurationManager:

var config = WebConfigurationManager.OpenWebConfiguration("~/Sites/" + requestDomain + "/"); 
(..) 
config.AppSettings.Settings["xxxx"].Value; 
1

Использование обработки XML:

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

// can call root.Elements(...)