2009-02-20 670 views
73

Tengo dos aplicaciones, una de consola y otra de ASP.NET. Ambos necesitan conocer la misma appSettings y connectionStrings. Entonces, idealmente, me gustaría usar la propiedad configSource de los archivos app.config/web.config para señalar eso a una ubicación central. Por ejemplo. Config de .NET configSource fuera de la carpeta del directorio de la aplicación

<connectionStrings configSource="D:\connectionStrings.config"/> 
<appSettings configSource="D:\appSettings.config"/> 

Eso, sin embargo falla con un error:

The configSource attribute is invalid.: The configSource 'D:\appSettings.config' is invalid. It must refer to a file in the same directory or in a subdirectory as the configuration file.

todos modos hay que seguir utilizando los administradores de configuración AppSettings/connectionStrings y obtener los valores desde una ubicación externa?
Me complace tener que agregar código para hacerlo, pero no quiero tener que reemplazar todo el sistema de administrador de configuración.

Respuesta

85

Otra solución es simplemente agregar el archivo de configuración en todos sus proyectos como un enlace en lugar de copiar el archivo a sus proyectos. A continuación, establezca la "Acción de compilación" del archivo en "Contenido" y "Copiar en el directorio de salida" a "Copiar si es más nuevo" y cuando compile el proyecto tendrá el archivo en el directorio de salida.

Para agregar el archivo como un enlace en el cuadro de diálogo "Agregar elemento existente", hay un botón Agregar con un menú desplegable. Elija "Agregar como enlace" del menú desplegable en el botón Agregar para completar el proceso.

+0

nice - mucho más fácil de entender para la gente que mi camino –

+9

hola, me gusta esta respuesta y he intentado aplicarla a mi propio proyecto, y todo parece funcionar bien cuando "publico" mi aplicación (db.config se copia a la raíz web como dijiste), pero no cuando se depura a través de VS y Cassini. En cambio, aparece la excepción "No se puede abrir el archivo configSource 'db.config'". ¿Hay algo que me falta para poder hacer esto? ¡Gracias! – Funka

+13

Por supuesto, justo después de que decido desglosarme y publicar un comentario pidiendo ayuda, lo averiguo enseguida. Noté que mi db.config también se ha copiado en la carpeta/bin /, así que actualicé mi web.config para anteponer esta ruta en su 'configSource' y todo parece ir bien. ¡Gracias de nuevo! – Funka

2

Puede colocar ambas configuraciones en el machine.config y luego están disponibles para todas sus aplicaciones en el servidor.

+0

Es una opción, pero no quiero (necesito) la configuración disponible para otras aplicaciones en la máquina. La preocupación son las cadenas de conexión, tienen nombres genéricos que pueden entrar en conflicto con otras aplicaciones. –

7

Puede cargar la configuración desde una ubicación arbitraria, pero no estará disponible a través de las propiedades estáticas de ConfigurationManager:

Configuration myConfig = ConfigurationManager.OpenExeConfiguration(path) 

(hay una sobrecarga que permite que los archivos multuple que se especificarán, a admite la jerarquía predeterminada/itinerancia del usuario/usuario-local.)

Perder las propiedades estáticas significa que todo el código debe tener en cuenta la configuración diferente.

+0

Esto requiere que se cargue todo el archivo de configuración. Solo necesito que appSettings y connectionStrings sean los mismos, el resto del archivo es diferente para cada aplicación, por lo que no resuelve el problema. –

+0

Toda la configuración está cargada por las propiedades normales (estáticas) de todos modos, por lo que no hay diferencia real. – Richard

+0

Además, podría simplemente usar su propio formato XML y agregar su nombre a los archivos de configuración de las aplicaciones y leerlo directamente. – Richard

16

Parece que es así. configSource debe estar en la misma carpeta o más profundo.

Usted podía, aunque no estoy seguro de que debe , use un enlace duro NTFS. [sonrisa enojada]

2

La solución que encontré funcionó mejor fue poner los archivos de configuración "compartidos" en un archivo central y luego usar un evento de preconstrucción en Visual Studio para copiarlos en una carpeta relativa de cada proyecto que necesitaba eso.

29

Bajo appsettings puede utilizar file = en lugar de configSource =

+1

Excelente hallazgo para mí! ¡¡Gracias!! Con esto, puedo anular las claves seleccionadas en AppSettings como se muestra en http://weblogs.asp.net/pwilson/archive/2003/04/09/5261.aspx –

2

tuve una gran lucha con este problema, pero he encontrado una buena solución para ello aquí: test run with external config

(Puede dirigir la ejecución de prueba para copiar archivos y directorios en el directorio de ejecución de prueba editando el archivo .testrunconfig.)

Aunque por qué el proyecto de tipo de prueba de unidad puede obtener configuraciones desde su propia app.config, pero no puede cargar archivos de configuración referenciados como una app.config normal es algo desconcertante para mí. Lo llamaría un error porque esperaría una aplicación de proyecto de prueba.config se comporta de la misma manera que la aplicación app.config se comporta, pero no es así.

3

Visual Studio 2015

Si tiene este problema con Web.Config la respuesta aceptada es correcta, pero sólo para ampliar ya que esto me tenía a mí mismo dando la cara de palma:

Cuando se agrega un archivo .config en su proyecto usando 'Agregar como enlace' y luego establezca la propiedad Copiar del enlace a 'Copiar si es más reciente' o 'Copiar siempre', luego el archivo físico se copiará en la carpeta/bin.

Por lo tanto, cuando se tiene una sección de configuración se define en Web.Config así:

<section name="mySpecialConfig" type="System.Configuration.AppSettingsSection" requirePermission="false" /> 

continuación, se debe definir el elemento de configuración relacionados con este aspecto:

<mySpecialConfig configSource="bin\MySpecialConfig.config"> 
    </mySpecialConfig> 

tal que los puntos configSource al archivo bin \ MySpecialConfig.config físico no al enlace Además, tenga en cuenta que la ruta es relativa ruta física.

Esto puede parecer ridículamente obvio, pero si no lo ha hecho antes, el archivo físico todavía no está en la carpeta \ bin, por lo que es posible que no haga clic de inmediato.

2

En el caso de las cadenas de conexión, de hecho es posible apuntar a un archivo compartido. Si el archivo compartido está en una red UNC, requiere privilegios administrativos en la máquina donde se alojará la aplicación.

Solución: En su web.config, use configSource para apuntar a un archivo de configuración local. Debido a las restricciones de .Net, debe estar al nivel del archivo de configuración raíz o por debajo del mismo. Acabo de apuntar a un archivo en la carpeta de aplicación en sí:

<connectionStrings configSource="ConnectionStrings.config" /> 

En una ubicación compartida que sea accesible por el usuario del grupo de aplicaciones, añadir el archivo de configuración que contiene las cadenas de conexión compartida. Este archivo no debe contener ningún xml que no sea la sección de connectionStrings. El archivo compartido ConnectionStrings.config se ve así:

<connectionStrings> 
    <clear/> 
    <add name="connString1" connectionString="connString1 info goes here"/> 
    <add name="connString2" connectionString="connString2 info goes here"/> 
</connectionStrings> 

Ahora el truco. Cree un enlace simbólico de Windows en su carpeta de aplicaciones apuntando al archivo de configuración compartido externo. Necesitará privilegios de administrador para hacer esto:

mklink ConnectionStrings.config \\someServer\someShare\someFolder\ConnectionStrings.config 

Acabamos burlado .Net. El sistema de configuración usará la configuración configSource para buscar cadenas de conexión en un archivo local llamado ConnectionStrings.config. El enlace simbólico se ve como un archivo en .Net, y el enlace simbólico se resuelve en el archivo de configuración compartido.

Advertencias: Los cambios en el archivo compartido no desencadenan automáticamente el reinicio de una aplicación en .Net. En el caso de IIS, el sitio web o grupo de aplicaciones deberá reiniciarse manualmente.

Debido a la necesidad de privilegios administrativos para crear el enlace simbólico, este enfoque puede no funcionar para todos. Hay dos alternativas relacionadas que pueden funcionar si el archivo compartido está en la misma unidad lógica: enlaces duros y cruces. Consulte this discussion y this discussion para obtener más información.

Cuestiones relacionadas