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?


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>

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>

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).


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.


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.