2011-04-20 53 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)" />

相关问题