Czy istnieje sposób na wykonanie operacji „Zamień lub Wstaw” za pomocą transformacji web.config?

183

Korzystam z transformacji web.config, jak opisano w poniższym poście, w celu wygenerowania konfiguracji dla różnych środowisk.

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

Mogę wykonać transformację „Zamień”, dopasowując klawisz, np

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

I mogę zrobić „wstawki” np

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

Ale to, co byłoby naprawdę znaleźć użyteczne jest transformacja ReplaceOrInsert, bo nie zawsze można polegać na oryginalny plik konfiguracyjny posiadające / nie mając pewnego klucza.

Czy jest na to sposób?

Chris Haines
źródło
podany link nie działa w tej chwili. Czy masz jakiś inny link do łatwego zrozumienia tej koncepcji?
Ashish-BeJovial
@AshishJain link działa dobrze dla mnie
Chris Haines

Odpowiedzi:

105

Znalazłem tanie obejście. To nie jest ładne i nie będzie działać dobrze, jeśli masz wiele elementów, które muszą być „Zamień lub Wstaw”.

Wykonaj czynności „Usuń”, a następnie „InsertAfter | InsertBefore”.

Na przykład,

<authorization xdt:Transform="Remove" />
<authorization xdt:Transform="InsertAfter(/configuration/system.web/authentication)">
  <deny users="?"/>
  <allow users="*"/>
</authorization>
phu
źródło
17
Jeśli używasz VS2012, istnieje teraz lepsze rozwiązanie. Zobacz poniżej stackoverflow.com/a/16679201/32055
Chris Haines
1
w razie potrzeby wstawi i zamieni „InsertIfMissing”?
Jessy
Wolę tę opcję od drugiej dzięki zastosowaniu InsertAfter. InsertIfMissing nie ma sensu, jeśli mimo to wykonujesz operację usuwania.
Shane Courtrille
125

W połączeniu z xdt:Transform="Remove"użyciem xdt:Transform="InsertIfMissing"w VS2012.

<authorization xdt:Transform="Remove" />
<authorization xdt:Transform="InsertIfMissing">
  <deny users="?"/>
  <allow users="*"/>
</authorization>
ADW334034
źródło
Idealny! Na to czekaliśmy.
Chris Haines
9
To wcale nie działa jak żądania OP.
BradLaney
2
Odpowiedź została zredagowana, aby wyraźniej pokazać, w jaki sposób odpowiada na pierwotne pytanie.
Bon
25
Nie rozumiem Jeśli go usuniesz, oczywiście będzie go brakować, w tym momencie jest to po prostu wkładka, prawda?
Chad Schouggins,
6
@ChadSchouggins niekoniecznie: Removezadanie usuwa tylko pierwsze wystąpienie. Niektóre elementy mogą mieć wiele wystąpień. Nie mogę sobie wyobrazić, że byś tego chciał, ale wtedy usunie to pierwsze wystąpienie i pominie InsertIfMissingzadanie. Ale miałbyś rację, gdyby RemoveAllzamiast tego użył .
Steven Liekens,
89

Użyj InsertIfMissingtransformacji, aby upewnić się, że istnieje appSetting.
Następnie użyj Replacetransformacji, aby ustawić jej wartość.

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

Możesz także użyć SetAttributestransformacji zamiast Replace. Różnica polega na tym, SetAttributesże nie dotyka węzłów potomnych.

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

Te techniki są znacznie lepsze niż usuwanie + wstawianie, ponieważ istniejące węzły nie są przenoszone na dół ich węzła nadrzędnego. Nowe węzły są dołączane na końcu. Istniejące węzły pozostają tam, gdzie są w pliku źródłowym.

Ta odpowiedź dotyczy tylko nowszych wersji programu Visual Studio (2012 lub nowszych).

Steven Liekens
źródło
7

Lepszą metodą było dla mnie wstawienie elementu tylko wtedy, gdy nie istnieje, ponieważ ustawiam tylko niektóre atrybuty. Usunięcie elementu odrzuciłoby wszelkie inne atrybuty elementu głównego, gdyby istniały.

przykład: web.config (bez elementu)

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

web.config (z elementem)

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

Używając Lokalizatora z wyrażeniem XPath, dodaję węzeł, jeśli nie istnieje, a następnie ustawiam mój atrybut:

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

oba wynikowe pliki web.config mają includeExceptionDetailInFaults = "true", a drugi zachowuje atrybut httpsHelpPageEnabled, którego nie zrobiłaby metoda remove / insert.

Dan
źródło
1
Podoba mi się ten pomysł, ale pojawia się błąd, jeśli element już istnieje „Żaden element w dokumencie źródłowym nie pasuje ...”. Oznacza to, że jeśli istnieje, to „nie” zawodzi, więc jest to błąd.
goodeye
Jest to technika, której potrzebujesz, gdy używasz wersji XDT, które nie obsługują nowego (ish) elementu „InsertIfMissing”.
IanBru