使用Web.Config转换的高级任务

有谁知道是否有一种方法来“变换”特定的值部分,而不是取代整个值或属性?

例如,我有几个appSettings条目指定不同web服务的Url。 这些条目在开发环境中与生产环境略有不同。 有些人比其他人微不足道

<!-- DEV ENTRY --> <appSettings> <add key="serviceName1_WebsService_Url" value="http://wsServiceName1.dev.domain.com/v1.2.3.4/entryPoint.asmx" /> <add key="serviceName2_WebsService_Url" value="http://ma1-lab.lab1.domain.com/v1.2.3.4/entryPoint.asmx" /> </appSettings> <!-- PROD ENTRY --> <appSettings> <add key="serviceName1_WebsService_Url" value="http://wsServiceName1.prod.domain.com/v1.2.3.4/entryPoint.asmx" /> <add key="serviceName2_WebsService_Url" value="http://ws.ServiceName2.domain.com/v1.2.3.4/entryPoint.asmx" /> </appSettings> 

请注意,在第一个条目中,唯一的区别是“.prod”中的“.dev”。 在第二项中,子域是不同的: “ws.ServiceName2”中的“ma1- lab.lab1”

到目前为止,我知道我可以在Web.Release.Config中做这样的事情:

 <add xdt:Locator="Match(key)" xdt:Transform="SetAttributes(value)" key="serviceName1_WebsService_Url" value="http://wsServiceName1.prod.domain.com/v1.2.3.4/entryPoint.asmx" /> <add xdt:Locator="Match(key)" xdt:Transform="SetAttributes(value)" key="serviceName2_WebsService_Url" value="http://ws.ServiceName2.domain.com/v1.2.3.4/entryPoint.asmx" /> 

然而,每次该Web服务的版本更新,我将不得不更新Web.Release.Config,这打破了简化我的web.config更新的目的。

我知道我也可以将这个url分成不同的部分,并独立更新,但我宁愿把它全部放在一个关键字中。

我已经浏览了可用的web.config转换,但似乎没有齿轮towars我想要完成。

这些是我用作参考的网站:

Vishal Joshi的博客 , MSDN帮助和Channel9video

任何帮助将非常感激!

-D

事实上,你可以做到这一点,但并不像你想像的那么容易。 您可以创build自己的configuration转换。 我刚刚在http://sedodream.com/2010/09/09/ExtendingXMLWebconfigConfigTransformation.aspx上写了一篇非常详细的博文。; 但是这里有一些亮点:

  • 创build类库项目
  • 参考Web.Publishing.Tasks.dll (%Program Files(x86)%MSBuild \ Microsoft \ VisualStudio \ v10.0 \ Web文件夹下)
  • 扩展Microsoft.Web.Publishing.Tasks.Transform类
  • 实现Apply()方法
  • 将组件放置在一个众所周知的位置
  • 使用xdt:Import来使新的转换可用
  • 使用转换

这是我为创build这个replace而创build的类

 namespace CustomTransformType { using System; using System.Text.RegularExpressions; using System.Xml; using Microsoft.Web.Publishing.Tasks; public class AttributeRegexReplace : Transform { private string pattern; private string replacement; private string attributeName; protected string AttributeName { get { if (this.attributeName == null) { this.attributeName = this.GetArgumentValue("Attribute"); } return this.attributeName; } } protected string Pattern { get { if (this.pattern == null) { this.pattern = this.GetArgumentValue("Pattern"); } return pattern; } } protected string Replacement { get { if (this.replacement == null) { this.replacement = this.GetArgumentValue("Replacement"); } return replacement; } } protected string GetArgumentValue(string name) { // this extracts a value from the arguments provided if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentNullException("name"); } string result = null; if (this.Arguments != null && this.Arguments.Count > 0) { foreach (string arg in this.Arguments) { if (!string.IsNullOrWhiteSpace(arg)) { string trimmedArg = arg.Trim(); if (trimmedArg.ToUpperInvariant().StartsWith(name.ToUpperInvariant())) { int start = arg.IndexOf('\''); int last = arg.LastIndexOf('\''); if (start <= 0 || last <= 0 || last <= 0) { throw new ArgumentException("Expected two ['] characters"); } string value = trimmedArg.Substring(start, last - start); if (value != null) { // remove any leading or trailing ' value = value.Trim().TrimStart('\'').TrimStart('\''); } result = value; } } } } return result; } protected override void Apply() { foreach (XmlAttribute att in this.TargetNode.Attributes) { if (string.Compare(att.Name, this.AttributeName, StringComparison.InvariantCultureIgnoreCase) == 0) { // get current value, perform the Regex att.Value = Regex.Replace(att.Value, this.Pattern, this.Replacement); } } } } } 

这里是web.config

 <?xml version="1.0"?> <configuration> <appSettings> <add key="one" value="one"/> <add key="two" value="partial-replace-here-end"/> <add key="three" value="three here"/> </appSettings> </configuration> 

这是我的configuration转换文件

 <?xml version="1.0"?> <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> <xdt:Import path="C:\Program Files (x86)\MSBuild\Custom\CustomTransformType.dll" namespace="CustomTransformType" /> <appSettings> <add key="one" value="one-replaced" xdt:Transform="Replace" xdt:Locator="Match(key)" /> <add key="two" value="two-replaced" xdt:Transform="AttributeRegexReplace(Attribute='value', Pattern='here',Replacement='REPLACED')" xdt:Locator="Match(key)"/> </appSettings> </configuration> 

这是转化后的结果

 <?xml version="1.0"?> <configuration> <appSettings> <add key="one" value="one-replaced"/> <add key="two" value="partial-replace-REPLACED-end"/> <add key="three" value="three here"/> </appSettings> </configuration> 

就像更新一样,如果您使用Visual Studio 2013,则应该引用%Program Files(x86)%MSBuild \ Microsoft \ VisualStudio \ v12.0 \ Web \ Microsoft.Web.XmlTransform.dll。