Расширенные задачи с использованием преобразования Web.Config - PullRequest
41 голосов
/ 26 мая 2010

Кто-нибудь знает, есть ли способ "преобразовать" определенные разделы значений вместо замены всего значения или атрибута?

Например, у меня есть несколько записей appSettings, которые задают 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>

Обратите внимание, что в первой записи единственное отличие - ". 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.Release.Config, что противоречит цели упрощения моих обновлений web.config.

Я знаю, что мог бы также разделить этот URL-адрес на разные разделы и обновлять их независимо, но я предпочитаю хранить все это в одном ключе.

Я просмотрел доступные преобразования web.config, но ничто не похоже на то, что я пытаюсь выполнить.

Это сайты, которые я использую для справки:

Блог Вишала Джоши , Справка MSDN и Канал 9 видео

Любая помощь будет принята с благодарностью!

Ответы [ 2 ]

67 голосов
/ 09 сентября 2010

На самом деле вы можете сделать это, но это не так просто, как вы думаете. Вы можете создать свое собственное преобразование конфигурации. Я только что написал очень подробное сообщение в блоге на 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>
3 голосов
/ 30 сентября 2014

Точно так же, как обновление, если вы используете Visual Studio 2013, вам следует вместо этого ссылаться на% Program Files (x86)% MSBuild \ Microsoft \ VisualStudio \ v12.0 \ Web \ Microsoft.Web.XmlTransform.dll.

...