Gibt es eine Möglichkeit, mithilfe der web.config-Transformation ein "Ersetzen oder Einfügen" durchzuführen?

182

Ich verwende die web.config-Transformation wie im folgenden Beitrag beschrieben, um Konfigurationen für verschiedene Umgebungen zu generieren.

http://vishaljoshi.blogspot.com/2009/03/web-deployment-webconfig-transformation_23.html

Ich kann eine "Ersetzen" -Transformation durchführen, indem ich den Schlüssel anpasse, z

<add key="Environment" value="Live" xdt:Transform="Replace" xdt:Locator="Match(key)" />

Und ich kann "Inserts" machen, zB

<add key="UseLivePaymentService" value="true" xdt:Transform="Insert" />

Was ich aber wirklich nützlich finden würde , ist eine ReplaceOrInsert-Umwandlung, da ich mich nicht immer darauf verlassen kann, dass die ursprüngliche Konfigurationsdatei einen bestimmten Schlüssel hat / nicht hat.

Gibt es eine Möglichkeit, dies zu tun?

Chris Haines
quelle
Der von Ihnen angegebene Link funktioniert derzeit nicht. Haben Sie einen anderen Link, um das Konzept leicht zu verstehen?
Ashish-BeJovial
@ AshishJain der Link funktioniert gut für mich
Chris Haines

Antworten:

104

Ich habe eine billige Problemumgehung gefunden. Es ist nicht schön und funktioniert nicht sehr gut, wenn Sie viele Elemente haben, die "Ersetzen oder Einfügen" sein müssen.

Führen Sie ein "Entfernen" und dann ein "InsertAfter | InsertBefore" durch.

Beispielsweise,

<authorization xdt:Transform="Remove" />
<authorization xdt:Transform="InsertAfter(/configuration/system.web/authentication)">
  <deny users="?"/>
  <allow users="*"/>
</authorization>
ein phu
quelle
17
Wenn Sie VS2012 verwenden, gibt es jetzt eine bessere Lösung. Siehe unten stackoverflow.com/a/16679201/32055
Chris Haines
1
wird "InsertIfMissing" bei Bedarf einfügen und ersetzen?
Jessy
Ich bevorzuge diese Option gegenüber der anderen dank der Verwendung von InsertAfter. InsertIfMissing macht keinen Sinn, wenn Sie trotzdem ein Entfernen durchführen.
Shane Courtrille
125

In Verbindung mit der xdt:Transform="Remove"Verwendung xdt:Transform="InsertIfMissing"in VS2012.

<authorization xdt:Transform="Remove" />
<authorization xdt:Transform="InsertIfMissing">
  <deny users="?"/>
  <allow users="*"/>
</authorization>
ADW334034
quelle
Perfekt! Darauf haben wir gewartet.
Chris Haines
9
Dies funktioniert überhaupt nicht als OP-Anforderung.
BradLaney
2
Die Antwort wurde bearbeitet, um deutlicher zu zeigen, wie die ursprüngliche Frage beantwortet wird.
Bon
25
Ich verstehe es nicht Wenn Sie es entfernen, wird es natürlich fehlen, es ist an dieser Stelle nur eine Einfügung, oder?
Chad Schouggins
6
@ChadSchouggins nicht unbedingt: Die RemoveAufgabe entfernt nur das erste Vorkommen. Einige Elemente können mehrfach vorkommen. Ich kann mir nicht vorstellen, dass Sie dies möchten, aber dann würde es das erste Vorkommen entfernen und die InsertIfMissingAufgabe überspringen . Aber du hättest recht gehabt, wenn er RemoveAllstattdessen verwendet hätte.
Steven Liekens
87

Verwenden Sie die InsertIfMissingTransformation, um sicherzustellen, dass die appSetting vorhanden ist.
Verwenden Sie dann die ReplaceTransformation, um den Wert festzulegen.

<appSettings>
  <add key="Environment" xdt:Transform="InsertIfMissing" xdt:Locator="Match(key)" />
  <add key="Environment" value="Live" xdt:Transform="Replace" xdt:Locator="Match(key)" />
</appSettings>

Sie können auch die SetAttributesTransformation anstelle von verwenden Replace. Der Unterschied besteht darin, dass SetAttributesuntergeordnete Knoten nicht berührt werden.

<appSettings>  
  <add key="UseLivePaymentService" xdt:Transform="InsertIfMissing" xdt:Locator="Match(key)" />
  <add key="UseLivePaymentService" value="true" xdt:Transform="SetAttributes" xdt:Locator="Match(key)" />
</appSettings>

Diese Techniken sind viel besser als Entfernen + Einfügen, da vorhandene Knoten nicht an den unteren Rand ihres übergeordneten Knotens verschoben werden. Neue Knoten werden am Ende angehängt. Bestehende Knoten bleiben dort, wo sie sich in der Quelldatei befinden.

Diese Antwort gilt nur für neuere Versionen von Visual Studio (2012 oder neuer).

Steven Liekens
quelle
7

Eine bessere Methode für mich war, das Element nur einzufügen, wenn es nicht existiert, da ich nur bestimmte Attribute setze. Durch Entfernen des Elements werden alle anderen Attribute des Hauptelements verworfen, sofern sie vorhanden sind.

Beispiel: web.config (ohne Element)

<serviceBehaviors>
    <behavior name="Wcf.ServiceImplementation.AllDigitalService_Behavior">
        <serviceMetadata httpGetEnabled="true" />
    </behavior>
</serviceBehaviors>

web.config (mit Element)

<serviceBehaviors>
    <behavior name="Wcf.ServiceImplementation.AllDigitalService_Behavior">
        <serviceDebug httpsHelpPageEnabled="true" />
        <serviceMetadata httpGetEnabled="true" />
    </behavior>
</serviceBehaviors>

Mit dem Locator mit einem XPath-Ausdruck füge ich den Knoten hinzu, falls er nicht vorhanden ist, und setze dann mein Attribut:

<serviceDebug xdt:Transform="Insert"
  xdt:Locator="XPath(/configuration/system.serviceModel/behaviors/serviceBehaviors/behavior[not(serviceDebug)])" />
<serviceDebug includeExceptionDetailInFaults="true" xdt:Transform="SetAttributes" />

Beide resultierenden web.config-Dateien haben includeExceptionDetailInFaults = "true" und die zweite behält das httpsHelpPageEnabled-Attribut bei, bei dem die Methode remove / insert dies nicht tun würde.

Dan
quelle
1
Diese Idee gefällt mir, aber ich erhalte eine Fehlermeldung, wenn das Element bereits vorhanden ist. "Kein Element im Quelldokument stimmt überein ...". Das heißt, wenn es existiert, schlägt das "nicht" fehl, es ist also ein Fehler.
Goodeye
Dies ist die Technik, die Sie benötigen, wenn Sie Versionen von XDT verwenden, die das neue (ish) "InsertIfMissing" -Element nicht unterstützen.
IanBru