Чи є спосіб зробити «Замінити або вставити», використовуючи перетворення web.config?


183

Я використовую перетворення web.config, як описано в публікації нижче, щоб генерувати конфігурації для різних середовищ.

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

Я можу здійснити перетворення «Замінити» шляхом зіставлення ключа, наприклад

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

І я можу робити "вставки", наприклад

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

Але те, що я дійсно вважаю корисним, це перетворення ReplaceOrInsert, оскільки я не завжди можу покластися на оригінальний файл конфігурації, який має / не має певного ключа.

Чи можна це зробити?


надане вами посилання наразі не працює. Чи є у вас якесь інше посилання, щоб зрозуміти концепцію легко?
Ashish-BeJovial

@AshishJain посилання працює для мене чудово
Кріс Хайнс

Відповіді:


105

Я знайшов дешеве рішення. Це не красиво і не спрацює дуже добре, якщо у вас є багато елементів, які потрібно "Замінити або вставити".

Зробіть "Видалити", а потім "InsertAfter | InsertBefore".

Наприклад,

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

17
Якщо ви використовуєте VS2012, тепер є краще рішення. Дивіться нижче stackoverflow.com/a/16679201/32055
Chris Haines

1
буде "InsertIfMissing" вставити та замінити, якщо потрібно?
Джессі

Я віддаю перевагу цьому варіанту над іншим завдяки використанню InsertAfter. InsertIfMissing не має сенсу, якщо ви все-таки робите видалення.
Шейн Кортрілл

125

У поєднанні з xdt:Transform="Remove"використанням xdt:Transform="InsertIfMissing"у VS2012.

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

Ідеально! Це ми чекали.
Кріс Хайнс

9
Це взагалі не відповідає вимогам ОП.
BradLaney

2
Відповідь відредаговано, щоб більш наочно продемонструвати, як вона відповідає на початкове запитання.
Бон

25
Я не розумію. Якщо ви виймете його, звичайно, він буде відсутній, це лише Вставка в той момент, правда?
Чад Шуґґінс

6
@ChadSchouggins не обов'язково: Removeзавдання видаляє лише перше виникнення. Деякі елементи можуть мати кілька випадків. Я не можу уявити, що ви цього хотіли б, але тоді це видалить перше явище і пропустить InsertIfMissingзавдання. Але ви були б праві, якби він використовував RemoveAllзамість цього.
Стівен Лікенс

89

Використовуйте InsertIfMissingперетворення, щоб переконатися в існуванні програми.
Потім використовуйте Replaceперетворення, щоб встановити його значення.

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

Ви також можете використовувати SetAttributesперетворення замість Replace. Різниця в тому, що SetAttributesне торкається дочірніх вузлів.

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

Ці методи набагато краще, ніж видалити + вставити, оскільки існуючі вузли не переміщені до нижньої частини їхнього батьківського вузла. Нові вузли додаються в кінці. Існуючі вузли залишаються там, де вони є у вихідному файлі.

Ця відповідь стосується лише новіших версій Visual Studio (2012 або новіших).


7

Для мене кращим методом було вставити елемент лише в тому випадку, якщо він не існує, оскільки я встановлюю лише певні атрибути. Видалення елемента відкине будь-які інші атрибути головного елемента, якби вони існували.

приклад: web.config (без елемента)

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

web.config (з елементом)

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

Використовуючи Locator з виразом XPath, я додаю вузол, якщо він не існує, і встановлюю свій атрибут:

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

обидва результуючі файли web.config містятьExceptionDetailInFaults = "true", а другий зберігає атрибут httpsHelpPageEnabled, де метод видалення / вставки не буде.


1
Мені подобається ця ідея, але я отримую помилку, якщо елемент вже існує "Жоден елемент у вихідному документі не відповідає ...". Тобто, якщо воно існує, "не" провалюється, тож це помилка.
goodeye

Це техніка, яка вам потрібна, коли ви використовуєте версії XDT, які не підтримують новий (ish) елемент "InsertIfMissing".
IanBru
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.