Asp.net
使用 Web.Config 轉換的高級任務
有誰知道是否有辦法“轉換”值的特定部分而不是替換整個值或屬性?
例如,我有幾個 appSettings 條目,它們為不同的 Web 服務指定了 Urls。這些條目在開發環境中與生產環境略有不同。有些比其他的不那麼微不足道
<!-- 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>請注意,在第一個條目中,唯一的區別是**“.dev”與“.prod”。在第二個條目上,子域不同:“ma1-lab.lab1”來自“ws.ServiceName2”**
到目前為止,我知道我可以在 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 轉換,但似乎沒有什麼適合我想要完成的任務。
這些是我用作參考的網站:
Vishal Joshi 的部落格、MSDN 幫助和Channel9 影片
任何幫助將非常感激!
-D
事實上,你可以做到這一點,但它並不像你想像的那麼容易。您可以創建自己的配置轉換。我剛剛在<http://sedodream.com/2010/09/09/ExtendingXMLWebconfigConfigTransformation.aspx>上寫了一篇關於此的非常詳細的部落格文章。但這裡有亮點:
- 創建類庫項目
- 參考 Web.Publishing.Tasks.dll (在 %Program Files (x86)%MSBuild\Microsoft\VisualStudio\v10.0\Web 文件夾下)
- 擴展 Microsoft.Web.Publishing.Tasks.Transform 類
- 實現 Apply() 方法
- 將組件放置在眾所周知的位置
- 使用 xdt:Import 使新轉換可用
- 使用變換
這是我為執行此替換而創建的類
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>這是我的配置轉換文件
<?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>