Transformación de configuración web no funciona


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.Depurar.config

<appSettings>
    <add  key="SMTPPort" value="58" xdt:Transform="Replace" xdt:Locator="Match(key)" />
</appSettings>

Y corro la aplicación en modo de depuración, pero mi puerto SMTP sigue tomando el valor de web.config, no web.Debug.config.

¿Puede alguien sugerir qué podría estar mal en esta configuración?

Author: Matt, 2012-01-12

7 answers

La Web.las transformaciones de configuración solo se aplican como parte de una operación de publicación.

Si desea que esto se haga como parte de una operación de compilación app.config, puede usar el complemento SlowCheetah-XML Transforms Visual Studio:

Http://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5

 132
Author: devdigital,
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-09-19 15:57:58

Visual Studio (2010 - 2017) desafortunadamente no lo soporta directamente mientras está depurando, solo está destinado a publicar - 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 existe una solución alternativa descrito en codeproject .

Describe cómo modificar el .msproj archivo para sobrescribir el actual web.config por la versión transformada.

Primero describiré esa solución como Opción 1 , pero recientemente he descubierto otra Opción 2 , que es más fácil de usar (por lo que puede desplazarse hacia abajo a la opción 2 directamente si lo desea):


Opción 1: He añadido las instrucciones tomadas del artículo original codeproject (ver el enlace de arriba), porque las capturas de pantalla ya se han ido, y no quiero perder la totalidad información:

VS.Net no hace ninguna transformación cuando está desarrollando y solo depura su entorno local. Pero hay algunos pasos que puede hacer para que esto suceda si lo desea.

  • Primero, cree las configuraciones que desee en VS.Net , asumiendo que la depuración y liberación predeterminadas no son suficientes para lo que está tratando de lograr.
  • Haga clic derecho en su web.config y seleccione Add Config Transforms - esto creará un dependiente configuración de transformación para cada una de sus configuraciones definidas.
  • Ahora puede cambiar el nombre de su web.config a web.base.config.
  • Añade un web.config a tu proyecto. No importa lo que hay en él porque se sobrescribirá cada vez que hagamos una compilación, pero queremos que sea parte del proyecto, por lo que VS.Net no nos da la ventana emergente "Su proyecto no está configurado para la depuración".
  • Edite su .csproj Archivo de proyecto y agregue la siguiente tarea TransformXml a la compilación posterior objetivo. Aquí puedes ver que transformaré el archivo web.base.config usando el web.[configuration].config y lo guardaré como web.config. Para obtener más detalles, por favor revise this Microsoft Q&A, y para obtener instrucciones sobre cómo extender la compilación, busque there.

Opción 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 el 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 reemplace el v14.0 en la ruta por el número de versión apropiado, por ejemplo, v11.0).

Para Visual Studio 2017, el esquema de nombres para la ruta ha cambiado: Por ejemplo, para la versión enterprise está aquí: C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\VisualStudio\v15.0\Web.
Asumo que para la versión profesional debe reemplazar Enterprise en la ruta por Professional. Si está utilizando la versión de vista previa, reemplace adicionalmente 2017 por Preview.

Compilar y poner el .archivo exe en un directorio, por ejemplo C:\MyTools\.

Uso: Puede usarlo en su evento post build (en propiedades del proyecto, seleccione Eventos Build, luego edite la línea de comandos Evento Post-build). Los parámetros de la línea de comandos son (ejemplo):

"C:\MyTools\TransformConfig.Exe " / d: Web.config / t: Web.Configur (Nombre de configuración).configuración: Web.Plantilla.config /b:"Proj (ProjectDir)\"

Es decir, primero el nombre del archivo de configuración, seguido por el archivo de configuración de transformación, seguido de una configuración de plantilla opcional, seguido de la ruta a su proyecto que contiene ambos archivos.

He agregado el parámetro opcional template config porque de lo contrario su configuración original completa sería sobrescrita por la transformación, lo que se puede evitar proporcionando una plantilla.

Cree la plantilla simplemente copiando la Web original.config y el nombre Web.Plantilla.config.

Nota:

  • Si lo prefiere, también puede copiar el archivo TransformConfig.exe a la ruta de Visual Studio mencionada anteriormente donde reside el Microsoft.Web.XmlTransform.dll y hacer referencia a él en todos sus proyectos donde necesite transformar sus configuraciones.

  • Para aquellos de ustedes que se preguntan por qué agregué Environment.ExitCode = x; asignaciones: Simplemente devolver un int desde Main no ayudó en el evento de compilación. Ver detalles aquí.

  • Si estás publicando tu proyecto y estás usando un Web.Plantilla.config, asegúrese de que hizo un rebuild en su solución con la configuración correcta (generalmente Release) antes de publicar. La razón es que la Web.Config se sobrescribe durante la depuración y puede terminar transformando el archivo incorrecto de lo contrario.

 21
Author: Matt,
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-05-17 07:30:20

Responder a tu pregunta no es sencillo, porque plantea un problema - si quieres transformar Web.config con Web.depurar.config - ¿dónde se debe almacenar el efecto de transformación? En la Web.config sí mismo? ¡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 mezclarlas para tener una solución genérica que funcione cuando realmente cambie la configuración de la solución activa desde depurar para liberar, etc. Aquí hay una solución simple:

  1. Cree sus transformaciones de configuración para configuraciones (Debug, Release, etc.)
  2. Rename Web.config file to Web.base.config - las transformaciones deben renombrarse automáticamente en consecuencia (Web.base.Debug.config, etc)
  3. Añada lo siguiente transformWebConfig.archivo XML proj a la carpeta del proyecto:
<?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>
  1. Navegue hasta las propiedades de su proyecto, elija Eventos de compilación y agregue el siguiente contenido a Después de la compilación línea de comandos del evento :
@if exist "%ProgramFiles(x86)%\MSBuild\12.0\bin" set PATH=%ProgramFiles(x86)%\MSBuild\12.0\bin;%PATH%
msbuild $(ProjectDir)transformWebConfig.proj /t:TransformWebConfig /p:CurrentConfig=$(ConfigurationName) /p:TargetProjectName=$(TargetPath)

Ahora, cuando construyes tu solución, una Web.el archivo de configuración se creará con transformaciones válidas para la configuración activa.

 20
Author: komsky,
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-01-21 15:05:58

Su pregunta inmediata ha sido respondida - la explicación es que la transformación se aplica en publish, no en build.

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 web.config limpiar y establecer todas las claves que varían en función del entorno en los respectivos archivos de transformación. Mi conclusión es que la solución más fácil y estable es para usar valores de depuración en la web original.config, de esa manera siempre están presentes cuando se realiza una depuración en Visual Studio.

Luego cree transformaciones para los diferentes entornos en los que desea publicar - prueba, integración, producción - lo que tenga. La funcionalidad ahora incorporada para transformar la web.los archivos de configuración en la publicación serán suficientes para esto. No hay necesidad de SlowCheetah o editar eventos de compilación ni archivos de proyecto. Si solo tienes proyectos web que es.

Si desea, también podrías tener la web.depurar.archivo de configuración 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.

 4
Author: Carolina Persson,
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-06-01 08:39:08

Use Octopus Deploy (Community edition es gratis) y deje que transforme el web.config para usted. Pasos:

  1. Configure Octopus para implementar su aplicación web
  2. Asegúrese de que su Web.Release.config tiene la propiedad Build Action establecida en Content al igual que su archivo principal web.config.

¡Eso es todo! Octopus hará el resto sin ninguna configuración especial. Una implementación predeterminada del sitio web de IIS hará esto de inmediato:introduzca la descripción de la imagen aquí

 1
Author: Matt Kocaj,
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-22 06:27:36

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 aplicación.config o cualquier otro archivo XML basado en la configuración de compilación

 0
Author: Amir,
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-09-18 10:40:48

Recientemente tuve el mismo problema con una web anterior .config archivado basado en.NET Framework 2.0. La solución era simplemente eliminar la web.espacio de nombres de configuración (xmlns acceso en configuración nodo raíz):

ANTES: <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">

DESPUÉS DE: <configuration>

 0
Author: rneto,
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-02-15 16:43:06