Uso de ConfigurationManager para cargar la configuración desde una ubicación arbitraria


Estoy desarrollando un componente de acceso a datos que se utilizará en un sitio web que contiene una mezcla de ASP clásico y ASP.NET páginas, y necesita una buena manera de administrar sus ajustes de configuración.

Me gustaría utilizar un personalizado ConfigurationSection, y para el ASP.NET páginas esto funciona muy bien. Pero cuando el componente se llama a través de COM interop desde una página ASP clásica, el componente no se ejecuta en el contexto de un ASP.NET solicitud y por lo tanto no tiene conocimiento de web.config.

¿Hay una manera de decir el ConfigurationManager para cargar la configuración desde una ruta arbitraria (por ejemplo, ..\web.config si mi ensamblado está en la carpeta /bin)? Si lo hay, entonces estoy pensando que mi componente puede volver a eso si el valor predeterminado ConfigurationManager.GetSection devuelve null para mi sección personalizada.

Cualquier otro enfoque a esto sería bienvenido!

Author: newfurniturey, 2008-08-07

8 answers

Prueba esto:

System.Configuration.ConfigurationFileMap fileMap = new ConfigurationFileMap(strConfigPath); //Path to your config file
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
 109
Author: Ishmaeel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-07 14:14:44

Otra solución es anular la ruta predeterminada del archivo de configuración del entorno.

Me parece la mejor solución para la carga de archivos de configuración de ruta no trivial, específicamente la mejor manera de adjuntar archivos de configuración a dll.

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

Ejemplo:

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

Se pueden encontrar más detalles en este blog.

Además, esta otra respuesta tiene una excelente solución, completa con código para actualizar la configuración de la aplicación y un objeto IDisposable a restablecer vuelve a su estado original. Con esto solución, puede mantener el ámbito de configuración temporal de la aplicación:

using(AppConfig.Change(tempFileName))
{
    // tempFileName is used for the app config during this context
}
 64
Author: Saturn Technologies,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:50

La respuesta de Ishmaeel generalmente funciona, sin embargo, encontré un problema, que es que usar OpenMappedMachineConfiguration parece perder los grupos de secciones heredados de la máquina.config. Esto significa que puede acceder a sus propias secciones personalizadas (que es todo el OP deseado), pero no a las secciones normales del sistema. Por ejemplo, este código no funcionará:

ConfigurationFileMap fileMap = new ConfigurationFileMap(strConfigPath);
Configuration configuration = ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
MailSettingsSectionGroup thisMail = configuration.GetSectionGroup("system.net/mailSettings") as MailSettingsSectionGroup;  // returns null

Básicamente, si pones un reloj en el configuration.SectionGroups, verás que system.net no está registrado como SectionGroup, por lo que es prácticamente inaccesible a través de la normal canal.

Hay dos maneras que encontré para solucionar esto. La primera, que no me gusta, es volver a implementar los grupos de sección del sistema copiándolos de la máquina.config en su propia web.config, por ejemplo,

<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>

No estoy seguro de que la propia aplicación web se ejecute correctamente después de eso, pero puede acceder a los grupos de secciones correctamente.

La segunda solución es en lugar de abrir su web.config como una configuración EXE, que probablemente esté más cerca de su función prevista de todos modos:

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!

Me atrevo a decir que ninguna de las respuestas proporcionadas aquí, ni la mía ni la de Ishmaeel, están usando estas funciones como lo pretendían los diseñadores de.NET. Pero, esto parece funcionar para mí.

 38
Author: Gavin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-29 02:52:01

Además de la respuesta de Ishmaeel, el método OpenMappedMachineConfiguration() siempre devolverá un objeto Configuration. Así que para comprobar si se cargó debe comprobar la propiedad HasFile donde true significa que vino de un archivo.

 10
Author: Joseph Daigle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-23 09:14:57

Proporcioné los valores de configuración a word hosted .nET Compoent de la siguiente manera.

Un componente de Biblioteca de clases.NET que se llama/aloja en MS Word. Para proporcionar valores de configuración a mi componente, creé winword.exe.config en C:\Program Files\Microsoft Office \ OFFICE11 carpeta. Debería poder leer los valores de configuración como lo hace en Traditional. NET.

string sMsg = System.Configuration.ConfigurationManager.AppSettings["WSURL"];
 4
Author: Iftikhar Ali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-22 09:27:08

Para ASP.NET use WebConfigurationManager:

var config = WebConfigurationManager.OpenWebConfiguration("~/Sites/" + requestDomain + "/");
(..)
config.AppSettings.Settings["xxxx"].Value;
 1
Author: Javier Cañon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-14 21:08:29

Utilice el procesamiento XML:

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

// can call root.Elements(...)
 1
Author: JoelFan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-08 22:18:57

Esto debería hacer el truco:

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "newAppConfig.config);

Fuente: https://www.codeproject.com/Articles/616065/Why-Where-and-How-of-NET-Configuration-Files

 0
Author: gatsby,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-09 10:53:32