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.