asp.net - visual - slowcheetah




Web Config Transform funktioniert nicht (5)

In einer .NET MVC 3.0-Anwendung habe ich in appSettings folgende Konfiguration:

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>

Zum Debuggen habe ich die folgende Konfigurationstransformation definiert:

web.Debug.config

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

Und ich web.config die Anwendung im Debug-Modus aus, aber mein SMTP-Port nimmt immer noch den Wert aus der web.config und nicht von web.Debug.config .

Kann jemand vorschlagen, was in dieser Konfiguration falsch sein könnte?



Die Beantwortung Ihrer Frage ist nicht einfach, da sie ein Problem darstellt - wenn Sie Web.config mit Web.debug.config transformieren möchten - wo der Transformationseffekt gespeichert werden soll? In Web.config selbst? Dies würde die Transformationsquelldatei überschreiben! Wahrscheinlich führt Visual Studio deshalb während Builds keine Transformationen durch.

Die vorherige Matt-Antwort ist gültig, aber Sie möchten möglicherweise eine Mischung aus einer generischen Lösung verwenden, die funktioniert, wenn Sie die aktive Lösungskonfiguration tatsächlich von Debug zu Release usw. ändern. Hier eine einfache Lösung:

  1. Erstellen Sie Ihre Konfigurationsumwandlungen für Konfigurationen (Debug, Release usw.).
  2. Datei " Web.config " in " Web.base.config umbenennen - Transformationen sollten automatisch entsprechend umbenannt werden ( Web.base.Debug.config usw.).
  3. Fügen Sie Ihrem XML- Projektordner die folgende XML-Datei "transformWebConfig.proj " hinzu:
<?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. Navigieren Sie zu Ihren Projekteigenschaften, wählen Sie Build Events aus, und fügen Sie der Befehlszeile für Post- Build-Ereignisse folgenden Inhalt hinzu :
@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)

Wenn Sie jetzt Ihre Lösung erstellen, wird eine Web.config-Datei mit gültigen Umwandlungen für die aktive Konfiguration erstellt.


Ihre unmittelbare Frage wurde beantwortet - die Erklärung ist, dass die Transformation beim Publizieren angewendet wird, nicht beim Build.

Ich denke jedoch, dass es keine Lösung dafür gibt, wie Sie erreichen können, was Sie erreichen möchten.

Ich habe seit ein paar Tagen mit diesem Problem zu kämpfen, auf der Suche nach einer Möglichkeit, web.config sauber zu halten und alle Schlüssel festzulegen, die je nach Umgebung in den jeweiligen Transformationsdateien variieren. Meine Schlussfolgerung ist, dass die einfachste und stabilste Lösung darin besteht, Debug-Werte in der ursprünglichen web.config zu verwenden. Auf diese Weise sind sie immer vorhanden, wenn Debug-Läufe in Visual Studio ausgeführt werden.

Erstellen Sie dann Transformationen für die verschiedenen Umgebungen, in denen Sie veröffentlichen möchten - Test, Integration, Produktion - was auch immer Sie haben. Die jetzt integrierte Funktionalität zur Umwandlung von web.config-Dateien beim Publizieren reicht dafür aus. Keine Notwendigkeit für SlowCheetah oder das Bearbeiten von Build-Events oder Projektdateien. Wenn Sie nur Webprojekte haben, ist es das.

Wenn Sie möchten, können Sie auch die Datei web.debug.config in Ihrer Projektmappe verwenden, um nur eine separate Datei mit allen Werten für die Entwicklungsumgebung aufzubewahren. Vergewissern Sie sich, dass die Werte nicht übernommen werden, wenn sie in Visual Studio ausgeführt werden, falls jemand anderes versucht, sie zu diesem Zweck zu verwenden!


Verwenden Sie Octopus Deploy (Community Edition ist kostenlos) und lassen Sie die web.config für Sie web.config . Schritte:

  1. Richten Sie Octopus für die Bereitstellung Ihrer Webanwendung ein
  2. Web.Release.config Sie sicher, dass für Ihre Web.Release.config die Build Action Eigenschaft auf Content gesetzt ist, genau wie Ihre Hauptdatei web.config .

Das ist es! Den Rest erledigt Octopus ohne spezielle Konfiguration. Eine standardmäßige IIS-Website-Bereitstellung führt dies standardmäßig aus:


Visual Studio (2010 - 2017) unterstützt es leider nicht direkt beim Debuggen, es ist nur für die Veröffentlichung gedacht - selbst mit der Erweiterung SlowCheetah (markierte Antwort) funktioniert es nicht für mich (nur für Projekte, die app.config verwenden und nicht web.config).

Beachten Sie, dass bei codeproject eine Problemumgehung beschrieben wird .

Es beschreibt, wie Sie die .msproj-Datei ändern, um die aktuelle web.config durch die umgesetzte Version zu überschreiben.

Ich werde diese Problemumgehung zunächst als Option 1 beschreiben , aber ich habe kürzlich eine weitere Option 2 herausgefunden , die einfacher zu verwenden ist (wenn Sie möchten, können Sie direkt zu Option 2 scrollen):

Option 1: Ich habe die Anweisungen aus dem ursprünglichen Artikel des Codeprojekts hinzugefügt (siehe Link oben), da die Screenshots dort bereits verschwunden sind und ich nicht die gesamte Information verlieren möchte:

VS.Net führt keine Transformation durch, wenn Sie Ihre lokale Umgebung entwickeln und nur debuggen. Sie können jedoch einige Schritte unternehmen, um dies zu ermöglichen, wenn Sie möchten.

  • Erstellen Sie zunächst die gewünschten Konfigurationen in VS.Net , wenn Sie davon ausgehen , dass das Standard-Debugging und das Standard-Release nicht ausreichen, was Sie erreichen möchten.
  • Klicken Sie mit der web.config auf Ihre web.config und wählen Sie web.config wird eine abhängige Transformationskonfiguration für jede Ihrer definierten Konfigurationen erstellt.
  • Nun können Sie Ihre web.config in web.base.config umbenennen.
  • Fügen web.config Ihrem Projekt eine web.config . Es spielt keine Rolle, was darin enthalten ist, denn es wird jedes Mal überschrieben, wenn wir einen Build durchführen, aber wir möchten, dass es Teil des Projekts ist. VS.Net gibt uns nicht das Popup "Ihr Projekt ist nicht für das Debuggen konfiguriert". oben.
  • Bearbeiten Sie Ihre .csproj Projektdatei und fügen Sie dem AfterBuild-Ziel die folgende TransformXml Aufgabe hinzu. Hier können Sie sehen, dass ich die Datei web.base.config mithilfe von web.[configuration].config und diese wird als web.config . Weitere Informationen finden Sie in den folgenden Microsoft-Fragen und Antworten. Anweisungen zum Erweitern des Builds finden Sie there .

Option 2:

Basierend auf this Antwort habe ich eine einfache Konsolen-App, TransformConfig.exe (in C # 6.0-Syntax) entwickelt:

using System;
using System.Linq;
using Microsoft.Web.XmlTransform;

namespace TransformConfig
{

  class Program
  {
    static int Main(string[] args)
    {
        var myDocumentsFolder = [email protected]"C:\Users\{Environment.UserName}\Documents";
        var myVsProjects = [email protected]"{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)
                                    ? [email protected]"{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);
    }

  }
}

Stellen Sie sicher, dass Sie die DLL "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.XmlTransform.dll" als Referenz "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.XmlTransform.dll" (dieses Beispiel gilt für VS 2015 für ältere Versionen.) Ersetzen Sie die v14.0 im Pfad durch die entsprechende Versionsnummer (z. B. v11.0 ).

Für Visual Studio 2017 hat sich das Benennungsschema für den Pfad geändert: Für die Unternehmensversion ist es beispielsweise hier: C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\VisualStudio\v15.0\Web .
Ich gehe davon aus, dass Sie für die Professional-Version Enterprise im Pfad durch Professional ersetzen müssen. Wenn Sie die Preview-Version verwenden, ersetzen Sie 2017 durch Preview .

Kompilieren Sie es und legen Sie die EXE-Datei in ein Verzeichnis ab, z. B. C:\MyTools\ .

Verwendung: Sie können es in Ihrem Post Build-Ereignis verwenden (in den Projekteigenschaften wählen Sie Build Events aus und bearbeiten Sie dann die Befehlszeile des Post Build-Ereignisses ). Befehlszeilenparameter sind (Beispiel):

"C: \ MyTools \ TransformConfig.Exe" /d:Web.config /t:Web.$(ConfigurationName).config /s:Web.Template.config / b: "$ (ProjectDir) \"

dh zuerst den Namen der Konfigurationsdatei, gefolgt von der Umwandlungs-Konfigurationsdatei, gefolgt von einer optionalen Vorlagenkonfiguration, gefolgt vom Pfad zu Ihrem Projekt, das beide Dateien enthält.

Ich habe den optionalen Parameter für die Vorlagenkonfiguration hinzugefügt, da ansonsten Ihre ursprüngliche vollständige Konfiguration durch die Transformation überschrieben würde, was durch die Bereitstellung einer Vorlage vermieden werden kann.

Erstellen Sie die Vorlage, indem Sie einfach die ursprüngliche Datei "Web.config" kopieren und "Web.Template.config" nennen.

Hinweis:

  • Wenn Sie möchten, können Sie die TransformConfig.exe Datei auch in den oben genannten Visual Studio-Pfad kopieren, in dem sich die Datei Microsoft.Web.XmlTransform.dll befindet, und in allen Ihren Projekten darauf verweisen, in denen Sie Ihre Konfigurationsdateien transformieren müssen.

  • Für diejenigen von Ihnen, die sich fragen, warum ich Environment.ExitCode = x; hinzugefügt habe Environment.ExitCode = x; Aufgaben: Die einfache Rückgabe eines Int von Main hat beim Build-Event nicht geholfen. Details finden Sie here.

  • Wenn Sie Ihr Projekt veröffentlichen und eine Web.Template.config verwenden, stellen Sie sicher, dass Sie Ihre Lösung vor der Veröffentlichung mit der richtigen Konfiguration (normalerweise Release) neu erstellt haben. Der Grund ist, dass Web.Config während des Debugging überschrieben wird und Sie möglicherweise die falsche Datei umwandeln.





web-config-transform