有没有办法使用web.config转换进行"替换或插入"?

Chr*_*nes 172 asp.net xslt web-config-transform xdt-transform

我正在使用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)" />
Run Code Online (Sandbox Code Playgroud)

我可以做"插入",例如

<add key="UseLivePaymentService" value="true" xdt:Transform="Insert" />
Run Code Online (Sandbox Code Playgroud)

但我真正觉得有用的是一个ReplaceOrInsert转换,因为我不能总是依赖原始配置文件有/没有某个键.

有没有办法做到这一点?

小智 116

与VS2012 结合xdt:Transform="Remove"使用xdt:Transform="InsertIfMissing".

<authorization xdt:Transform="Remove" />
<authorization xdt:Transform="InsertIfMissing">
  <deny users="?"/>
  <allow users="*"/>
</authorization>
Run Code Online (Sandbox Code Playgroud)

  • 我不明白.如果你删除它,当然它会丢失,那只是一个插入,对吧? (21认同)
  • 但如果此标记已存在,则不会替换它. (14认同)
  • 这根本不是OP请求. (9认同)
  • @ChadSchouggins不一定:`Remove`任务只删除第一次出现.某些元素可能会出现多次.我无法想象你会想要这个,但它会删除第一次出现并跳过`InsertIfMissing`任务.但如果他改用"RemoveAll",那你就是对的. (6认同)
  • 答案已经过编辑,以更清楚地说明它如何回答原始问题. (2认同)

an *_*phu 102

我找到了一个廉价的解决方法.它不漂亮,如果你有很多需要"替换或插入"的元素,它将无法正常工作.

执行"删除",然后执行"InsertAfter | InsertBefore".

例如,

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

  • 如果使用VS2012,现在有一个更好的解决方案.见下文http://stackoverflow.com/a/16679201/32055 (17认同)

Ste*_*ens 76

使用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>
Run Code Online (Sandbox Code Playgroud)

您也可以使用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>
Run Code Online (Sandbox Code Playgroud)

这些技术比删除+插入要好得多,因为现有节点不会移动到其父节点的底部.最后附加新节点.现有节点保留在源文件中的位置.

此答案仅适用于较新版本的Visual Studio(2012或更新版本).


小智 7

对我来说更好的方法是仅在元素不存在时插入元素,因为我只设置了某些属性.删除元素将丢弃主元素的任何其他属性(如果存在).

示例:web.config(不带元素)

<serviceBehaviors>
    <behavior name="Wcf.ServiceImplementation.AllDigitalService_Behavior">
        <serviceMetadata httpGetEnabled="true" />
    </behavior>
</serviceBehaviors>
Run Code Online (Sandbox Code Playgroud)

web.config(带元素)

<serviceBehaviors>
    <behavior name="Wcf.ServiceImplementation.AllDigitalService_Behavior">
        <serviceDebug httpsHelpPageEnabled="true" />
        <serviceMetadata httpGetEnabled="true" />
    </behavior>
</serviceBehaviors>
Run Code Online (Sandbox Code Playgroud)

使用带有XPath表达式的Locator,我添加节点(如果它不存在)然后设置我的属性:

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

两个生成的web.config文件都包含includeExceptionDetailInFaults ="true",第二个文件保留了httpsHelpPageEnabled属性,其中remove/insert方法不会.