2008-08-07 15 views
110

Estoy desarrollando un componente de acceso a datos que se usará en un sitio web que contiene una combinación de páginas ASP y ASP.NET clásicas, y necesita una buena forma de administrar sus configuraciones .Uso de ConfigurationManager para cargar config desde una ubicación arbitraria

Me gustaría utilizar un ConfigurationSection personalizado, y para las páginas ASP.NET esto funciona muy bien. Pero cuando se llama al componente a través de la 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 una manera de contar la ConfigurationManager simplemente cargar la configuración de una ruta arbitraria (por ejemplo ..\web.config si mi conjunto se encuentra en la carpeta /bin)? Si hay, entonces estoy pensando que mi componente puede volver a eso si el predeterminado ConfigurationManager.GetSection devuelve null para mi sección personalizada.

¡Cualquier otro enfoque para esto sería bienvenido!

+2

Ver http: // stackoverflow.com/questions/3912727/openmappedexeconfiguration-vs-openexeconfiguration/6599688#6599688 –

Respuesta

104

Prueba esto:

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

¿Cómo puedo obtener el valor _programmatically_ ** strConfigPath ** para mi aplicación ASP.NET _WebForms_ alojada en *** http: //sub.domain.com/virtualDir2/*** y ruta *** C: \ Portals \ App1 \ v2 *** y _config file_ en *** C: \ Portals \ App1 \ v2 \ web.config ***? – Kiquenet

+0

@Kiquenet: El punto de la pregunta es que strConfigPath es una ubicación _arbitrary_. En otras palabras, usted decide cuál es la ruta, en lugar de confiar en el marco para intentar cargar un archivo de configuración desde su ubicación convencional. Supongo que [Server.MapPath] (https://msdn.microsoft.com/en-us/library/system.web.httpserverutility.mappath (v = vs.110) .aspx) le daría la ubicación absoluta para cualquier archivos dentro de su solución. – Ishmaeel

+0

Quizás 'var config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration (" ~/web.config ");' – Kiquenet

9

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

37

La respuesta de Ishmaeel generalmente funciona, sin embargo, encontré un problema, que es que el uso de 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 se desea OP), 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 se pone un reloj en la configuration.SectionGroups, verá que system.net no está registrado como un sectionGroup, por lo que es prácticamente inaccesible vía la normalidad canales

Existen dos formas de solucionar este problema. El primero, que no me gusta, es volver a implementar los grupos de secciones del sistema copiándolos de machine.config en su propio web.config, p.

<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 la propia aplicación web funcionará correctamente después de eso, pero se puede acceder a los sectionGroups correctamente.

La segunda solución es lugar para abrir su web.config como una configuración EXE, que es probablemente más cercano a 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 proveídas aquí, ni mina o Ishmaeel's usa bastante estas funciones como pensaban los diseñadores de .NET. Pero, esto parece funcionar para mí.

+1

También puede usar la sobrecarga ConfigurationManager.OpenExeConfiguration (String) para el mismo propósito. Ver: http://www.codeproject.com/KB/dotnet/mysteriesofconfiguration3.aspx#t2_1 –

4

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

Un componente .NET Class Library que se llama/aloja en MS Word. Para proporcionar valores de configuración a mi componente, creé winword.exe.config en la carpeta C: \ Archivos de programa \ Microsoft Office \ OFFICE11. Debería poder leer valores de configuraciones como lo hace en Traditional .NET.

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

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

La considero la mejor solución para la carga de archivos de configuración 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"); 

Más detalles se pueden encontrar en this blog.

Además, this other answer tiene una excelente solución, completa con código para actualizar la configuración de la aplicación y un objeto IDisposable para restablecerlo a su estado original. Con esta solución , se puede mantener la configuración de aplicaciones de ámbito temporal:

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

Esto también funciona para cargar archivos web.config. Lo uso para cargar un web.config en lugar de app.config para una aplicación de consola relacionada con la tarea. ;) –

+1

Esto (y las otras respuestas aquí) no funciona para mí. Había agregado el código en la función program.cs: Main(). Mi configuración contiene una redirección de versión de ensamblaje (vea http://stackoverflow.com/questions/30165393/avoid-assembly-reference-problems-generally) pero la redirección no afecta cuando la configuración se cambia manualmente. – Undercover1989

+1

¿Utilizaste "APP_CONFIG_FILE"? –

1

Para uso ASP.NET WebConfigurationManager:

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

Uso de procesamiento XML:

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

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