C'è un modo per fare un "Sostituisci o Inserisci" usando la trasformazione web.config?


183

Sto usando la trasformazione web.config come descritto nel post seguente per generare configurazioni per ambienti diversi.

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

Posso fare una trasformazione "Sostituisci" abbinando la chiave, ad es

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

E posso fare "Inserti" ad es

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

Ma ciò che troverei davvero utile è una trasformazione ReplaceOrInsert, poiché non posso sempre fare affidamento sul file di configurazione originale con / non avere una determinata chiave.

C'è un modo per fare questo?


il link fornito non funziona al momento. Hai qualche altro link per capire facilmente il concetto?
Ashish-BeJovial

@AshishJain il link funziona bene per me
Chris Haines,

Risposte:


105

Ho trovato una soluzione economica. Non è carino e non funzionerà molto bene se hai molti elementi che devono essere "Sostituisci o Inserisci".

Fai un "Rimuovi" e poi un "InsertAfter | InsertBefore".

Per esempio,

<authorization xdt:Transform="Remove" />
<authorization xdt:Transform="InsertAfter(/configuration/system.web/authentication)">
  <deny users="?"/>
  <allow users="*"/>
</authorization>

17
Se si utilizza VS2012, ora esiste una soluzione migliore. Vedi sotto stackoverflow.com/a/16679201/32055
Chris Haines,

1
"InsertIfMissing" inserirà e sostituirà se necessario?
Jessy,

Preferisco questa opzione rispetto all'altra grazie all'uso di InsertAfter. InsertIfMissing non ha senso se si esegue comunque una rimozione.
Shane Courtrille,

125

In combinazione con l' xdt:Transform="Remove"uso xdt:Transform="InsertIfMissing"in VS2012.

<authorization xdt:Transform="Remove" />
<authorization xdt:Transform="InsertIfMissing">
  <deny users="?"/>
  <allow users="*"/>
</authorization>

Perfetto! Questo è quello che stavamo aspettando.
Chris Haines,

9
Questo non funziona affatto come richieste di OP.
BradLaney,

2
La risposta è stata modificata per dimostrare più chiaramente come risponde alla domanda originale.
Bon

25
Non capisco Se lo rimuovi, ovviamente mancherà, a quel punto è solo un inserto, giusto?
Chad Schouggins,

6
@ChadSchouggins non necessariamente: l' Removeattività rimuove solo la prima occorrenza. Alcuni elementi possono avere più occorrenze. Non riesco a immaginare che lo vorresti, ma poi rimuoverà la prima occorrenza e salterebbe l' InsertIfMissingattività. Ma avresti avuto ragione se avesse usato RemoveAllinvece.
Steven Liekens,

89

Utilizzare la InsertIfMissingtrasformazione per assicurarsi che l'appSetting esista.
Quindi utilizzare la Replacetrasformazione per impostarne il valore.

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

È inoltre possibile utilizzare la SetAttributestrasformazione anziché Replace. La differenza è che SetAttributesnon tocca i nodi figlio.

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

Queste tecniche sono molto meglio di rimuovere + inserire perché i nodi esistenti non vengono spostati nella parte inferiore del nodo principale. Nuovi nodi vengono aggiunti alla fine. I nodi esistenti rimangono dove sono nel file di origine.

Questa risposta si applica solo alle versioni più recenti di Visual Studio (2012 o più recenti).


7

Un metodo migliore per me è stato quello di inserire l'elemento solo se non esiste poiché sto solo impostando determinati attributi. La rimozione dell'elemento eliminerebbe qualsiasi altro attributo dell'elemento principale se esistesse.

esempio: web.config (senza elemento)

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

web.config (con elemento)

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

Usando il Localizzatore con un'espressione XPath, aggiungo il nodo se non esiste e quindi imposto il mio attributo:

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

entrambi i file web.config risultanti hanno includeExceptionDetailInFaults = "true" e il secondo conserva l'attributo httpsHelpPageEnabled in cui il metodo remove / insert non lo sarebbe.


1
Mi piace questa idea, ma visualizzo un errore se l'elemento esiste già "Nessun elemento nel documento di origine corrisponde ...". Cioè, se esiste, il "non" sta fallendo, quindi è un errore.
arrivederci,

Questa è la tecnica di cui hai bisogno quando usi le versioni di XDT che non supportano il nuovo (ish) elemento "InsertIfMissing".
IanBru,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.