Чи є спосіб зробити «Замінити або вставити», використовуючи перетворення 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.