En una aplicación .NET MVC 3.0 tengo la siguiente configuración en appSettings
:
web.config
<appSettings>
<add key="SMTPHost" value="mail.domain.com"/>
<add key="SMTPUsername" value="[email protected]"/>
<add key="SMTPPort" value="25"/>
<add key="SMTPPwd" value="mypassword"/>
<add key="EmailFrom" value="[email protected]"/>
</appSettings>
Para la depuración, tengo definida la siguiente transformación de configuración:
web.Debug.config
<appSettings>
<add key="SMTPPort" value="58" xdt:Transform="Replace" xdt:Locator="Match(key)" />
</appSettings>
Y ejecuto la aplicación en modo de depuración, pero mi puerto SMTP todavía toma el valor del web.config
, noweb.Debug.config
.
¿Alguien puede sugerir qué podría estar mal en esta configuración?
Visual Studio (2010 - 2019) desafortunadamente no lo admite directamente mientras está depurando, solo está destinado a la publicación; incluso con la extensión SlowCheetah (respuesta marcada) no funciona para mí (solo para proyectos que usan app.config en lugar de web.config).
Tenga en cuenta que hay una solución alternativa descrita en codeproject .
Describe cómo modificar el archivo .msproj para sobrescribir el web.config actual por la versión transformada.
Primero describiré esa solución como Opción 1 , pero recientemente descubrí otra Opción 2 , que es más fácil de usar (por lo que puede desplazarse hacia abajo hasta la opción 2 directamente si lo desea):
Opción 1: agregué las instrucciones tomadas del artículo del proyecto de código original (vea el enlace de arriba), porque las capturas de pantalla ya se han ido y no quiero perder toda la información:
VS.Net no realiza ninguna transformación cuando está desarrollando y simplemente depurando su entorno local. Pero hay algunos pasos que puede seguir para que esto suceda si lo desea.
web.config
y seleccione Agregar transformaciones de configuración ; esto creará una configuración de transformación dependiente para cada una de sus configuraciones definidas.web.config
aweb.base.config
.web.config
a tu proyecto. No importa lo que está en ella, ya que se sobrescribirá cada vez que hace una compilación pero queremos que parte del proyecto de manera VS.Net no nos la da "su proyecto no está configurado para la depuración" emergente arriba..csproj
archivo de proyecto y agregue la siguienteTransformXml
tarea al destino AfterBuild. Aquí puede ver que voy a transformar elweb.base.config
archivo usando elweb.[configuration].config
y lo guardaré comoweb.config
. Para obtener más información, consulte estas preguntas y respuestas de Microsoft y, para obtener instrucciones sobre cómo extender la compilación, consulte allí .Opcion 2:
Basado en esta respuesta, he desarrollado una aplicación de consola simple, TransformConfig.exe (en la sintaxis de C # 6.0):
using System; using System.Linq; using Microsoft.Web.XmlTransform; namespace TransformConfig { class Program { static int Main(string[] args) { var myDocumentsFolder = $@"C:\Users\{Environment.UserName}\Documents"; var myVsProjects = $@"{myDocumentsFolder}\Visual Studio 2015\Projects"; string srcConfigFileName = "Web.config"; string tgtConfigFileName = srcConfigFileName; string transformFileName = "Web.Debug.config"; string basePath = myVsProjects + @"\"; try { var numArgs = args?.Count() ?? 0; if (numArgs == 0 || args.Any(x=>x=="/?")) { Console.WriteLine("\nTransformConfig - Usage:"); Console.WriteLine("\tTransformConfig.exe /d:tgtConfigFileName [/t:transformFileName [/s:srcConfigFileName][/b:basePath]]"); Console.WriteLine($"\nIf 'basePath' is just a directory name, '{basePath}' is preceeded."); Console.WriteLine("\nTransformConfig - Example (inside PostBuild event):"); Console.WriteLine("\t\"c:\\Tools\\TransformConfig.exe\" /d:Web.config /t:Web.$(ConfigurationName).config /s:Web.Template.config /b:\"$(ProjectDir)\\\""); Environment.ExitCode = 1; return 1; } foreach (var a in args) { var param = a.Trim().Substring(3).TrimStart(); switch (a.TrimStart().Substring(0,2).ToLowerInvariant()) { case "/d": tgtConfigFileName = param ?? tgtConfigFileName; break; case "/t": transformFileName = param ?? transformFileName; break; case "/b": var isPath = (param ?? "").Contains("\\"); basePath = (isPath == false) ? $@"{myVsProjects}\" + param ?? "" : param; break; case "/s": srcConfigFileName = param ?? srcConfigFileName; break; default: break; } } basePath = System.IO.Path.GetFullPath(basePath); if (!basePath.EndsWith("\\")) basePath += "\\"; if (tgtConfigFileName != srcConfigFileName) { System.IO.File.Copy(basePath + srcConfigFileName, basePath + tgtConfigFileName, true); } TransformConfig(basePath + tgtConfigFileName, basePath + transformFileName); Console.WriteLine($"TransformConfig - transformed '{basePath + tgtConfigFileName}' successfully using '{transformFileName}'."); Environment.ExitCode = 0; return 0; } catch (Exception ex) { var msg = $"{ex.Message}\nParameters:\n/d:{tgtConfigFileName}\n/t:{transformFileName}\n/s:{srcConfigFileName}\n/b:{basePath}"; Console.WriteLine($"TransformConfig - Exception occurred: {msg}"); Console.WriteLine($"TransformConfig - Processing aborted."); Environment.ExitCode = 2; return 2; } } public static void TransformConfig(string configFileName, string transformFileName) { var document = new XmlTransformableDocument(); document.PreserveWhitespace = true; document.Load(configFileName); var transformation = new XmlTransformation(transformFileName); if (!transformation.Apply(document)) { throw new Exception("Transformation Failed"); } document.Save(configFileName); } } }
Asegúrese de agregar la DLL
"C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.XmlTransform.dll"
como referencia (este ejemplo se aplica a VS 2015, para versiones anteriores, reemplacev14.0
en la ruta por el número de versión apropiado, por ejemplov11.0
).Para Visual Studio 2017, el esquema de nomenclatura para la ruta ha cambiado: Por ejemplo, para la versión de la empresa es aquí:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\VisualStudio\v15.0\Web
.Supongo que para la versión profesional debe reemplazar
Enterprise
en la ruta porProfessional
. Si está utilizando la versión de vista previa, reemplace adicionalmente2017
porPreview
.He aquí un resumen de cómo el camino ha cambiado para diferentes versiones de Visual Studio (si no tiene la versión de la empresa puede que tenga que sustituir
Enterprise
porProfessional
en el camino):Compílelo y coloque el archivo .exe en un directorio, por ejemplo
C:\MyTools\
.Uso: puede usarlo en su evento posterior a la compilación (en las propiedades del proyecto , seleccione Eventos de compilación y luego edite la línea de comando del evento posterior a la compilación ). Los parámetros de la línea de comandos son (ejemplo):
es decir, primero el nombre del archivo de configuración, seguido del archivo de configuración de transformación, seguido de una configuración de plantilla opcional, seguida de la ruta a su proyecto que contiene ambos archivos.
He agregado el parámetro de configuración de plantilla opcional porque, de lo contrario, la transformación sobrescribirá su configuración original completa, lo que puede evitarse proporcionando una plantilla.
Cree la plantilla simplemente copiando el Web.config original y asígnele el nombre Web.Template.config.
Nota:
Si lo prefiere, también puede copiar el
TransformConfig.exe
archivo a la ruta de Visual Studio mencionada anteriormente dondeMicrosoft.Web.XmlTransform.dll
reside y consultarlo en todos sus proyectos donde necesita transformar sus configuraciones.Para aquellos de ustedes que se preguntan por qué agregué
Environment.ExitCode = x;
asignaciones: simplemente devolver un int de Main no ayudó en el evento de compilación. Vea los detalles aquí.Si está publicando su proyecto y está utilizando un Web.Template.config, asegúrese de haber reconstruido su solución con la configuración correcta (generalmente Release) antes de publicar. La razón es que Web.Config se sobrescribe durante la depuración y, de lo contrario, podría terminar transformando el archivo incorrecto.
fuente
Responder a su pregunta no es simple, porque plantea un problema, si desea transformar Web.config con Web.debug.config, ¿dónde se debe almacenar el efecto de transformación? ¿En el propio Web.config? ¡Esto sobrescribiría el archivo fuente de transformación! Probablemente es por eso que Visual Studio no realiza transformaciones durante las compilaciones.
La respuesta anterior de Matt es válida, pero es posible que desee combinarlos para tener una solución genérica que funcione cuando realmente cambie la configuración de la solución activa de depuración a versión, etc. Aquí hay una solución simple:
Web.config
el archivo aWeb.base.config
: las transformaciones deben cambiar el nombre automáticamente en consecuencia (Web.base.Debug.config
, etc.)<?xml version="1.0" encoding="utf-8" ?> <Project ToolsVersion="4.0" DefaultTargets="TransformWebConfig" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v12.0\Web\Microsoft.Web.Publishing.Tasks.dll" /> <Target Name="TransformWebConfig"> <TransformXml Source="Web.base.config" Transform="Web.base.$(CurrentConfig).config" Destination="Web.config" /> </Target> </Project>
Ahora, cuando cree su solución, se creará un archivo Web.config con transformaciones válidas para la configuración activa.
fuente
'"$(MSBuildBinPath)\msbuild.exe" $(ProjectDir)TransformWebConfig.proj /t:TransformWebConfig /p:CurrentConfig=$(ConfigurationName) /p:TargetProjectName=$(TargetPath)
y actualizadav12.0
av14.0
en el archivo .proj.12.0
a14.0
para VS 2017 encontré la respuesta aquí no estoy seguro de por qué nadie la ha mencionado anteriormente, ya que parece ser una solución muy popular. Muy fácil también. Asegúrese de ver el comentario de IOrlandoni el 5 de marzo de 2019 para que funcione en VS 2017 y todas las versiones.
Básicamente es un dos pasos. Primero, edita el archivo .csproj, agregando el código a continuación. En segundo lugar, crea una nueva configuración web.base.config y copia allí el web.config existente. Después de hacer eso, cualquier compilación sobrescribirá su web.config con la transformación deseada.
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\WebApplications\Microsoft.WebApplication.targets" /> <Target Name="BeforeBuild"> <TransformXml Source="Web.Base.config" Transform="Web.$(Configuration).config" Destination="Web.config" /> </Target>
fuente
Web.config
deContent
aNone
, puede usarSource="Web.config" Destination="$(TargetPath).config"
(o quizás para algunos tipos de proyectosDestination="$(TargetDir)Web.config"
). También moví la transformación aAfterBuild
, ya que ya no es necesario hacerlo antes de copiar los archivos.bin
.Su pregunta inmediata ha sido respondida: la explicación es que la transformación se aplica en la publicación, no en la compilación.
Sin embargo, creo que no ofrece una solución sobre cómo lograr lo que quieres hacer.
He estado luchando con este problema exacto durante unos días, buscando una manera de mantener limpio web.config y configurar todas las claves que varían según el entorno en los archivos de transformación respectivos. Mi conclusión es que la solución más fácil y estable es usar valores de depuración en el archivo web.config original, de esa manera siempre estarán presentes cuando se ejecuta la depuración en Visual Studio.
Luego, cree transformaciones para los diferentes entornos en los que desea publicar: prueba, integración, producción, lo que sea que tenga. La funcionalidad ahora incorporada para transformar archivos web.config en la publicación será suficiente para esto. No es necesario utilizar SlowCheetah ni editar eventos de compilación ni archivos de proyecto. Si solo tiene proyectos web, eso es.
Si lo desea, también puede tener el archivo web.debug.config en su solución, solo para mantener un archivo separado con todos los valores pertenecientes al entorno de desarrollo. Sin embargo, asegúrese de comentar que los valores no se aplican cuando se ejecuta en Visual Studio, en caso de que alguien más intente usarlo para ese propósito.
fuente
Use Octopus Deploy (la edición Community es gratuita) y deje que transforme el archivo
web.config
por usted. Pasos:Web.Release.config
tenga laBuild Action
propiedad configuradaContent
como suweb.config
archivo principal .¡Eso es! Octopus hará el resto sin ninguna configuración especial. Una implementación predeterminada del sitio web de IIS hará esto de inmediato:
fuente
Aparentemente hay una extensión para Visual Studio 2015
https://visualstudiogallery.msdn.microsoft.com/05bb50e3-c971-4613-9379-acae2cfe6f9e
Este paquete le permite transformar su app.config o cualquier otro archivo XML basado en la configuración de compilación
fuente
new
mundo como oración.Recientemente tuve el mismo problema con un archivo web.config anterior basado en .NET Framework 2.0. La solución fue simplemente eliminar el espacio de nombres de web.config ( attibute xmlns en el nodo raíz de configuración ):
ANTES DE:
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
DESPUÉS:
<configuration>
fuente