Usando ConfigurationManager para cargar la configuración desde una ubicación arbitraria

StackOverflow https://stackoverflow.com/questions/4738

Pregunta

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

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

¿Hay alguna manera de decirle al ConfigurationManager para simplemente cargar la configuración desde una ruta arbitraria (p. ej. ..\web.config si mi asamblea está en el /bin carpeta)?Si lo hay, entonces estoy pensando que mi componente puede recurrir a eso si el valor predeterminado ConfigurationManager.GetSection devoluciones null para mi sección personalizada.

¡Cualquier otro enfoque sobre esto sería bienvenido!

¿Fue útil?

Solución

Prueba esto:

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

Otros consejos

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

Considero que es la mejor solución para la carga de archivos de configuración de rutas no triviales, 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 IDisposable objeto para restablecerlo a su estado original.Con esta solución, puede mantener la configuración de la aplicación temporal alcanzada:

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

La respuesta de Ismaeel generalmente funciona, sin embargo, encontré un problema, que es que usar OpenMappedMachineConfiguration Parece perder los grupos de secciones heredados de machine.config.Esto significa que puede acceder a sus propias secciones personalizadas (que es todo lo que OP quería), 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á que system.net no está registrado como un grupo de secciones, por lo que es prácticamente inaccesible a través de los canales normales.

Hay dos formas que encontré para solucionar este problema.La primera, que no me gusta, es volver a implementar los grupos de secciones del sistema copiándolos desde machine.config a su propio 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 aplicación web se ejecute correctamente después de eso, pero puedes acceder a la sección Grupos correctamente.

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

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 Ismaeel, utilizan estas funciones como lo pretendieron los diseñadores de .NET.Pero esto parece funcionar para mí.

Además de la respuesta de Ismaeel, el método OpenMappedMachineConfiguration() siempre devolverá un Configuration objeto.Entonces, para verificar si se cargó, debe verificar el HasFile propiedad donde verdadero significa que proviene de un archivo.

Proporcioné los valores de configuración para el componente .nET alojado en Word de la siguiente manera.

Un componente de la 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 la carpeta C:\Program Files\Microsoft Office\OFFICE11.Debería poder leer los valores de configuración como lo hace en .NET tradicional.

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

¡La respuesta aceptada es incorrecta!

Lanza la siguiente excepción al acceder a la propiedad AppSettings:

No se puede convertir un objeto de tipo 'System.Configuration.DefaultSection' para escribir 'System.Configuration.AppSettingsSection'.

Aquí está la solución correcta:

System.Configuration.ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = "YourFilePath";
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

Para ASP.NET utilice WebConfigurationManager:

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

Utilice procesamiento XML:

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

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

Esto debería funcionar :

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

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top