2011-04-20 51 views
133

我正在使用web.config轉換,如下面的帖子所述,以便爲不同的環境生成配置。有沒有辦法使用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)" /> 

我可以做「Inserts」例如

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

但我會真的找到有用的是ReplaceOrInsert轉型,因爲我不能總是依賴於具有/不具有某些關鍵的原始配置文件。

有沒有辦法做到這一點?

回答

89

我發現了一個便宜的解決方法。如果你有很多需要被「替換或插入」的元素,它不會很好,並且不能很好地工作。

做一個「刪除」,然後一個「InsertAfter | InsertBefore」。

例如,

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

如果使用VS2012,現在有更好的解決方案。見下面http://stackoverflow.com/a/16679201/32055 – 2013-05-22 09:37:45

+1

將「InsertIfMissing」插入和替換如果需要? – Jessycormier 2014-02-12 14:15:59

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" /> 

這兩個結果的網絡。配置文件有includeExceptionDetailInFaults =「true」,第二個保留了httpsHelpPageEnabled屬性,其中remove/insert方法不會。

+1

我喜歡這個想法,但是如果元素已經存在,我得到一個錯誤「源文檔中沒有元素匹配...」。也就是說,如果它存在,那麼「不」是失敗的,所以這是一個錯誤。 – goodeye 2012-03-09 00:46:29

+0

這是您在使用不支持新(ish)「InsertIfMissing」元素的XDT版本時所需的技巧。 – IanBru 2016-10-03 14:52:04

105

結合xdt:Transform="Remove"在VS2012中使用xdt:Transform="InsertIfMissing"

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

完美!這就是我們一直在等待的。 – 2013-05-22 09:37:02

+0

有沒有類似的「InsertAfterIfMissing」? – 2013-05-28 13:59:33

+14

但是,如果這個標籤已經存在,它不會被替換。 – 2013-12-26 04:40:56

50

使用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或更新版本)。

0

下面創建一個新的密鑰是相同的密鑰不存在。如果存在的話,它只是取代現有的。

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

相關問題