Расширенные задачи с использованием преобразования Web.config
-
04-10-2019 - |
Вопрос
Кто-нибудь знает, есть ли способ «преобразовать» специфические разделы значений вместо того, чтобы заменять все значение или атрибут?
Например, у меня есть несколько записей приложений, которые указывают URL для разных веб-сайтов. Эти записи немного отличаются в среде Dev, чем производственная среда. Некоторые менее тривиальные, чем другие
<!-- 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" от ".проница". На второй записи поддомен отличается: "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" />
Однако, каждый раз, когда версия для этого WebService обновляется, мне пришлось бы обновить Web.welease.config, что поражает цель Simplfying My Web.config.
Я знаю, что я мог бы также разделить этот URL в разные разделы и обновлять их самостоятельно, но я скорее все в одном ключ.
Я просматривал доступные преобразования Web.config, но ниотязы, кажется, присутствуют завещающие завещание, что я пытаюсь сделать.
Это веб-сайты, которые я использую в качестве ссылки:
Блог Вишала Джоши, MSDN Help, а также Channel9 Video.
Любая помощь приветствуется!
Потрясающий
Решение
На самом деле вы можете сделать это, но это не так просто, как вы думаете. Вы можете создать собственную конфигурацию преобразования. Я только что написал очень подробный пост блога в http://sedodream.com/2010/09/09/extendingXmlwebconfigconfigtransformation.aspx. в соответствии с этим. Но вот утешится:
- Создать проект библиотеки класса
- Справочник Web.publishing.tasks.dll. (Под% программных файлов (X86)% MSBUILD Microsoft Visualstudio v10.0 Web)
- Продлить Microsoft.Web.publishing.tasks.transform класс
- Реализовать метод Apply ()
- Поместите сборку в хорошо известное местоположение
- Используйте XDT: Импорт, чтобы сделать новый преобразование
- Использовать преобразование
Вот класс, который я создал, чтобы сделать это заменить
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>
Другие советы
Так же, как обновление, если вы используете Visual Studio 2013, вы должны ссылаться на% программных файлов (X86)% Msbuild Microsoft VisualStudio V12.0 Web Microsoft.web.xmltransform.dll.