Есть ли способ сделать «Заменить или вставить», используя преобразование 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, поскольку я не всегда могу полагаться на исходный файл конфигурации, имеющий / не имеющий определенный ключ.

Есть какой-либо способ сделать это?


предоставленная вами ссылка не работает на данный момент. У вас есть другая ссылка, чтобы легко понять концепцию?
— Ашиш-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
— Крис Хейнс

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
Это совсем не так, как запросы OP.
— БрэдЛейни

2
Ответ был отредактирован, чтобы более четко продемонстрировать, как он отвечает на исходный вопрос.
— Бон,

25
Я не понимаю Если вы удалите его, конечно, он будет отсутствовать, это просто вставка в этот момент, верно?
— Чед Шуггинс

6
@ChadSchouggins не обязательно: Removeзадача удаляет только первое вхождение. Некоторые элементы могут иметь несколько вхождений. Я не могу представить, что вы захотите этого, но тогда это удалит первое вхождение и пропустит InsertIfMissingзадачу. Но ты был бы прав, если бы использовал RemoveAllвместо этого.
— Стивен Лиекенс

89

Используйте InsertIfMissingпреобразование, чтобы убедиться, что appSetting существует.
Затем используйте 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>

Используя локатор с выражением XPath, я добавляю узел, если он не существует, и затем устанавливаю свой атрибут:

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

оба результирующих файла web.config имеют includeExceptionDetailInFaults = "true", а второй сохраняет атрибут httpsHelpPageEnabled, а метод удаления / вставки - нет.


1
Мне нравится эта идея, но я получаю сообщение об ошибке, если элемент уже существует "Ни один элемент в исходном документе не соответствует ...". То есть, если оно существует, «not» терпит неудачу, поэтому это ошибка.
— Goodeye

Это метод, который вам нужен, когда вы используете версии XDT, которые не поддерживают новый (ish) элемент «InsertIfMissing».
— Янвру
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.