有什么办法可以使用web.config转换进行“替换或插入”吗?


182

我正在使用以下帖子中所述的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链接对我而言很好
Chris Haines

Answers:


104

我找到了一种便宜的解决方法。如果您有很多需要“替换或插入”的元素,那么它不是很漂亮,效果也不好。

先执行“删除”,然后执行“ 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”会插入并替换吗?
Jessy 2014年

由于使用了InsertAfter,因此我更喜欢此选项。如果您仍然要执行Remove,则InsertIfMissing毫无意义。
Shane Courtrille

125

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

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

完善!这就是我们一直在等待的。
克里斯·海恩斯

9
根本不像OP请求那样。
BradLaney 2014年

2
答案已经过编辑,可以更清楚地说明它如何回答原始问题。
苯教

25
我不明白 如果删除它,它肯定会丢失,那时候它只是一个插入,对吗?
Chad Schouggins,2014年

6
@ChadSchouggins不一定:该Remove任务仅删除第一次出现的事件。一些元素可以多次出现。我无法想象您会想要这样做,但随后它将删除第一次出现的内容并跳过InsertIfMissing任务。但是如果他RemoveAll改用的话,那你是对的。
史蒂文·里肯斯

87

使用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>

这些技术比remove + insert更好,因为现有节点不会移到其父节点的底部。新节点将附加在末尾。现有节点将保留在源文件中的位置。

此答案仅适用于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表达式的Locator,如果节点不存在,则添加该节点,然后设置我的属性:

<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属性,而remove / insert方法不会。


1
我喜欢这个主意,但是如果元素已经存在“源文档中没有元素匹配...”,我将收到错误消息。也就是说,如果存在,则“ not”失败,因此是错误。
goodeye 2012年

这是在使用不支持new(ish)“ InsertIfMissing”元素的XDT版本时需要的技术。
IanBru
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.