Existe-t-il un moyen de faire un «Remplacer ou insérer» à l'aide de la transformation web.config?

183

J'utilise la transformation web.config comme décrit dans l'article ci-dessous afin de générer des configurations pour différents environnements.

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

Je peux faire une transformation "Remplacer" en faisant correspondre la clé, par exemple

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

Et je peux faire des "insertions" par exemple

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

Mais ce que je trouverais vraiment utile, c'est une transformation ReplaceOrInsert, car je ne peux pas toujours compter sur le fichier de configuration d'origine ayant / n'ayant pas une certaine clé.

Y a-t-il un moyen de faire ça?

Chris Haines
la source
le lien que vous avez fourni ne fonctionne pas pour le moment. Avez-vous un autre lien pour comprendre facilement le concept?
Ashish-BeJovial
@AshishJain le lien fonctionne bien pour moi
Chris Haines

Réponses:

105

J'ai trouvé une solution de contournement bon marché. Ce n'est pas joli et ne fonctionnera pas très bien si vous avez beaucoup d'éléments qui doivent être "Remplacer ou insérer".

Faites un "Remove" puis un "InsertAfter | InsertBefore".

Par exemple,

<authorization xdt:Transform="Remove" />
<authorization xdt:Transform="InsertAfter(/configuration/system.web/authentication)">
  <deny users="?"/>
  <allow users="*"/>
</authorization>
un phu
la source
17
Si vous utilisez VS2012, il existe désormais une meilleure solution. Voir ci-dessous stackoverflow.com/a/16679201/32055
Chris Haines
1
"InsertIfMissing" va-t-il insérer et remplacer si nécessaire?
Jessy
Je préfère cette option à l'autre grâce à l'utilisation de InsertAfter. InsertIfMissing n'a aucun sens si vous faites quand même un Remove.
Shane Courtrille
125

En conjonction avec l' xdt:Transform="Remove"utilisation xdt:Transform="InsertIfMissing"dans VS2012.

<authorization xdt:Transform="Remove" />
<authorization xdt:Transform="InsertIfMissing">
  <deny users="?"/>
  <allow users="*"/>
</authorization>
ADW334034
la source
Parfait! C'est ce que nous attendions.
Chris Haines
9
Cela ne correspond pas du tout aux demandes OP.
BradLaney
2
La réponse a été modifiée pour montrer plus clairement comment elle répond à la question initiale.
Bon
25
Je ne comprends pas. Si vous le supprimez, bien sûr, il va manquer, c'est juste un insert à ce stade, non?
Chad Schouggins
6
@ChadSchouggins pas nécessairement: la Removetâche supprime uniquement la première occurrence. Certains éléments peuvent avoir plusieurs occurrences. Je ne peux pas imaginer que vous souhaitiez cela, mais cela supprimerait la première occurrence et ignorerait la InsertIfMissingtâche. Mais vous auriez eu raison s'il avait utilisé à la RemoveAllplace.
Steven Liekens
89

Utilisez la InsertIfMissingtransformation pour vous assurer que appSetting existe.
Utilisez ensuite la Replacetransformation pour définir sa valeur.

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

Vous pouvez également utiliser la SetAttributestransformation au lieu de Replace. La différence est que SetAttributescela ne touche pas les nœuds enfants.

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

Ces techniques sont bien meilleures que supprimer + insérer car les nœuds existants ne sont pas déplacés vers le bas de leur nœud parent. Les nouveaux nœuds sont ajoutés à la fin. Les nœuds existants restent là où ils se trouvent dans le fichier source.

Cette réponse s'applique uniquement aux versions plus récentes de Visual Studio (2012 ou plus récentes).

Steven Liekens
la source
7

Une meilleure méthode pour moi était d'insérer l'élément uniquement s'il n'existe pas puisque je ne définis que certains attributs. La suppression de l'élément annulerait tous les autres attributs de l'élément principal s'ils existaient.

exemple: web.config (sans élément)

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

web.config (avec élément)

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

En utilisant le localisateur avec une expression XPath, j'ajoute le nœud s'il n'existe pas, puis je définis mon attribut:

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

les deux fichiers web.config résultants ont includeExceptionDetailInFaults = "true" et le second préserve l'attribut httpsHelpPageEnabled alors que la méthode remove / insert ne le ferait pas.

Dan
la source
1
J'aime cette idée, mais j'obtiens une erreur si l'élément existe déjà "Aucun élément dans le document source ne correspond à ...". Autrement dit, s'il existe, le "non" échoue, donc c'est une erreur.
revoir
C'est la technique dont vous avez besoin lorsque vous utilisez des versions de XDT qui ne prennent pas en charge le nouvel élément (ish) "InsertIfMissing".
IanBru