Преобразование веб-конфигурации не работает


в приложении .NET MVC 3.0 у меня есть следующая конфигурация в appSettings:

web.конфигурации

<appSettings>
<add key="SMTPHost" value="mail.domain.com"/>
    <add key="SMTPUsername" value="user@gmail.com"/>
    <add key="SMTPPort" value="25"/>
    <add key="SMTPPwd" value="mypassword"/>
    <add key="EmailFrom" value="notific@gmail.com"/>
</appSettings>

для отладки у меня определено следующее преобразование конфигурации:

web.Отлаживать.конфигурации

<appSettings>
    <add  key="SMTPPort" value="58" xdt:Transform="Replace" xdt:Locator="Match(key)" />
</appSettings>

и я запускаю приложение в режиме отладки, но мой SMTP-порт все еще принимает значение из web.config, а не web.Debug.config.

может ли кто-нибудь предположить, что может быть неправильно в этой конфигурации?

7 72

7 ответов:

Веб.преобразования конфигурации применяются только как часть операции публикации.

Если вы хотите, чтобы это было сделано как часть app.config операция сборки, затем вы можете использовать плагин SlowCheetah - XML Transforms Visual Studio:

http://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5

Visual Studio (2010 - 2017) нет, к сожалению не непосредственно поддерживайте его во время отладки, он предназначен только для публикации - даже с расширением SlowCheetah (отмеченный ответ) он не работает для меня (только для проектов, использующих приложение.конфигурация, а не веб.конфигурация.)

Примечание что есть решениеописано в codeproject.

он описывает, как изменить этот.файл msproj для перезаписи текущего веб-узла.конфиг по преобразованной версии.

я сначала опишу этот обходной путь как 1, но я недавно узнал еще один 2, который проще в использовании (так что вы можете прокрутить вниз до варианта 2 напрямую, если хотите):


Вариант 1: я добавил инструкции, взятые из оригинала статьи codeproject (см. ссылку выше), потому что на экране кадры уже ушли, и я не хочу потерять всю информацию:

VS.Net не выполняет никаких преобразований, когда вы разрабатываете и просто отлаживаете свою локальную среду. Но есть несколько шагов, которые вы можете сделать, чтобы это произошло, если вы хотите.

  • во-первых, создайте конфигурации, которые вы хотите в VS.Net, предполагая, что отладки и выпуска по умолчанию недостаточно для того, что вы пытаетесь выполнить.
  • право нажмите на web.config и выберите Добавить Преобразования Конфигурации - это создаст зависимую конфигурацию преобразования для каждой из ваших определенных конфигураций.
  • теперь вы можете переименовать свой web.config to web.base.config.
  • добавить a web.config в проект. Это не имеет значения, что в нем, потому что он будет перезаписан каждый раз, когда мы делаем сборку, но мы хотим, чтобы это часть проекта так VS.Net не дает нам "ваш проект не настроен для Отладка" всплывающее окно.
  • редактировать Файл и добавить следующее TransformXml задача для цели AfterBuild. Здесь вы можете видеть, что я буду преобразовывать С помощью web.[configuration].config и он сохранит его как web.config. Для получения дополнительной информации, пожалуйста, проверьте этой Microsoft Q&A, и для получения инструкций, как расширить сборку, смотрите здесь.

Вариант 2:

на основе на этой ответ, я разработал простое консольное приложение, TransformConfig.exe (в синтаксисе C# 6.0):

using System;
using System.Linq;
using Microsoft.Web.XmlTransform;

namespace TransformConfig
{

  class Program
  {
    static int Main(string[] args)
    {
        var myDocumentsFolder = $@"C:\Users\{Environment.UserName}\Documents";
        var myVsProjects = $@"{myDocumentsFolder}\Visual Studio 2015\Projects";

        string srcConfigFileName = "Web.config";
        string tgtConfigFileName = srcConfigFileName;
        string transformFileName = "Web.Debug.config";
        string basePath = myVsProjects + @"\";
        try
        {

            var numArgs = args?.Count() ?? 0;
            if (numArgs == 0 || args.Any(x=>x=="/?"))
            {
                Console.WriteLine("\nTransformConfig - Usage:");
                Console.WriteLine("\tTransformConfig.exe /d:tgtConfigFileName [/t:transformFileName [/s:srcConfigFileName][/b:basePath]]");
                Console.WriteLine($"\nIf 'basePath' is just a directory name, '{basePath}' is preceeded.");
                Console.WriteLine("\nTransformConfig - Example (inside PostBuild event):");
                Console.WriteLine("\t\"c:\Tools\TransformConfig.exe\"  /d:Web.config /t:Web.$(ConfigurationName).config /s:Web.Template.config /b:\"$(ProjectDir)\\"");
                Environment.ExitCode = 1;
                return 1;
            }

            foreach (var a in args)
            {
                var param = a.Trim().Substring(3).TrimStart();
                switch (a.TrimStart().Substring(0,2).ToLowerInvariant())
                {
                    case "/d":
                        tgtConfigFileName = param ?? tgtConfigFileName;
                        break;
                    case "/t":
                        transformFileName = param ?? transformFileName;
                        break;
                    case "/b":
                        var isPath = (param ?? "").Contains("\");
                        basePath = (isPath == false)
                                    ? $@"{myVsProjects}\" + param ?? ""
                                    : param;
                        break;
                    case "/s":
                        srcConfigFileName = param ?? srcConfigFileName;
                        break;
                    default:
                        break;
                }
            }
            basePath = System.IO.Path.GetFullPath(basePath);
            if (!basePath.EndsWith("\")) basePath += "\";
            if (tgtConfigFileName != srcConfigFileName)
            {
                System.IO.File.Copy(basePath + srcConfigFileName,
                                     basePath + tgtConfigFileName, true);
            }
            TransformConfig(basePath + tgtConfigFileName, basePath + transformFileName);
            Console.WriteLine($"TransformConfig - transformed '{basePath + tgtConfigFileName}' successfully using '{transformFileName}'.");
            Environment.ExitCode = 0;
            return 0;
        }
        catch (Exception ex)
        {
            var msg = $"{ex.Message}\nParameters:\n/d:{tgtConfigFileName}\n/t:{transformFileName}\n/s:{srcConfigFileName}\n/b:{basePath}";
            Console.WriteLine($"TransformConfig - Exception occurred: {msg}");
            Console.WriteLine($"TransformConfig - Processing aborted.");
            Environment.ExitCode = 2;
            return 2;
        }
    }

    public static void TransformConfig(string configFileName, string transformFileName)
    {
        var document = new XmlTransformableDocument();
        document.PreserveWhitespace = true;
        document.Load(configFileName);

        var transformation = new XmlTransformation(transformFileName);
        if (!transformation.Apply(document))
        {
            throw new Exception("Transformation Failed");
        }
        document.Save(configFileName);
    }

  }
}

убедитесь, что вы добавляете DLL "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.XmlTransform.dll"в качестве ссылки (этот пример относится к VS 2015, для более старых версий замените v14.0 в путь по соответствующему номеру версии, например,v11.0).

на Visual Studio 2017, схема именования для пути изменилась: например, для версии enterprise она находится здесь: C:\Program Files (x86)\Microsoft Visual Studio17\Enterprise\MSBuild\Microsoft\VisualStudio\v15.0\Web.
Я полагаю, что для профессиональной версии вам нужно заменить Enterprise в путь Professional. Если вы используете предварительную версию, дополнительно заменить 2017 by Preview.

скомпилировать и поставить .exe-файл в каталог, например C:\MyTools\.

использование: Вы можете использовать его в своем post build event (in свойства проекта выберите События Построения, затем измените командная строка события после сборки). Параметры командной строки (пример):

"C:\MyTools\TransformConfig.Exe " / d:Web.config /t: Web.$(Имя конфигурации).config /s: Web.Шаблон.конфиг /б:"$(Каталог_проекта)\"

т. е. сначала имя файла конфигурации, затем файл конфигурации преобразования, затем необязательный шаблон конфигурации, а затем путь к вашему проекту, содержащему оба файла.

я добавил необязательный параметр конфигурации шаблона, поскольку в противном случае исходная полная конфигурация будет перезаписана преобразованием, чего можно избежать, предоставив шаблон.

создайте шаблон, просто скопировав исходный веб.config и назовите его Web.Шаблон.конфиг.

Примечание:

  • если вы предпочитаете, вы также можете скопировать TransformConfig.exe файл в путь Visual Studio, упомянутый выше, где Microsoft.Web.XmlTransform.dll проживает и обратитесь к этому во всех ваших проектах, где вам нужно преобразовать ваши конфигурации.

  • для тех из вас, кто удивляется, почему я добавил Environment.ExitCode = x; назначения: простое возвращение int из Main не помогло в событии сборки. Смотрите подробности здесь.

  • если вы публикуете свой проект и используете веб.Шаблон.конфигурации, убедитесь, что вы сделали восстановить на вашем решении с правильной конфигурацией (обычно Выпуска), прежде чем публиковать. Причина в том, что в Интернете.Конфигурация перезаписывается во время отладки, и в противном случае вы можете преобразовать неправильный файл.

ответить на ваш вопрос не просто, потому что это создает проблему - если вы хотите преобразовать веб.конфиг с Web.отлаживать.config-где должен храниться эффект преобразования? в web.конфиг сам по себе? Это будет перезаписать исходный файл преобразования! Вероятно, именно поэтому Visual Studio не выполняет преобразования во время сборки.

предыдущий ответ Matt действителен, но вы можете смешать их, чтобы иметь общее решение, которое работает, когда вы фактически меняете активное решение конфигурацию с debug на Release и т. д. Вот простое решение:

  1. создайте свои преобразования конфигурации для конфигураций (Debug, Release и т. д.)
  2. переименовать до Web.base.config - преобразования должны автоматически переименовать соответственно (Web.base.Debug.config, etc)
  3. добавить следующее transformWebConfig.proj XML file в папку проекта:
<?xml version="1.0" encoding="utf-8" ?>
<Project ToolsVersion="4.0" DefaultTargets="TransformWebConfig" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v12.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
  <Target Name="TransformWebConfig">
    <TransformXml Source="Web.base.config" Transform="Web.base.$(CurrentConfig).config" Destination="Web.config" />
  </Target>
</Project>
  1. перейдите к свойствам проекта, выберите События Построения и добавить следующий контент в командная строка события после сборки:
@if exist "%ProgramFiles(x86)%\MSBuild.0\bin" set PATH=%ProgramFiles(x86)%\MSBuild.0\bin;%PATH%
msbuild $(ProjectDir)transformWebConfig.proj /t:TransformWebConfig /p:CurrentConfig=$(ConfigurationName) /p:TargetProjectName=$(TargetPath)

теперь, когда вы строите свое решение, веб.конфигурационный файл будет создан с допустимыми преобразованиями для активной конфигурации.

на ваш непосредственный вопрос был дан ответ-объяснение заключается в том, что преобразование применяется к публикации, а не к сборке.

однако, я думаю, что он не предлагает решение о том, как достичь того, что вы хотите сделать.

Я боролся с этой точной проблемой в течение нескольких дней, ища способ сохранить веб.config очистите и установите все ключи, которые зависят от среды в соответствующих файлах преобразования. Мой вывод заключается в том, что самый простой и самый стабильным решением является использование отладочных значений в исходной сети.config, таким образом, они всегда присутствуют при выполнении отладки в Visual Studio.

затем создайте преобразования для различных сред, которые вы хотите опубликовать - тест, интеграция, производство - все, что у вас есть. Теперь встроенная функциональность для преобразования веб.для этого достаточно конфигурационных файлов на публикации. Нет необходимости в SlowCheetah или редактирования событий сборки или файлов проекта. Если у вас есть только веб-проекты, которые есть.

Если вы хотите, вы также можете иметь веб.отлаживать.конфигурационный файл в вашем решении, просто чтобы сохранить отдельный файл со всеми значениями, относящимися к среде разработки. Обязательно прокомментируйте в нем, что значения не применяются при запуске в Visual Studio, хотя, если кто-то еще попытается использовать его для этой цели!

использовать Осьминог Развернуть (Community edition является бесплатным) и пусть он преобразует web.config для вас. Шаги:

  1. настройка Octopus для развертывания веб-приложения
  2. убедитесь, что ваш Web.Release.config имеет Build Action свойство имеет значение Content так же, как ваш главный .

вот именно! Осьминог сделает все остальное без каких-либо специальных настроек. Развертывание веб-узла IIS по умолчанию будет делать это из коробка:enter image description here

по-видимому, есть расширение для Visual Studio 2015

https://visualstudiogallery.msdn.microsoft.com/05bb50e3-c971-4613-9379-acae2cfe6f9e

этот пакет позволяет преобразовать ваше приложение.config или любой другой XML-файл на основе конфигурации сборки

недавно у меня была такая же проблема со старым web.конфигурации подано на основе .NET Framework 2.0. Решение было просто удалить веб -.пространство имен конфигурации (xmlns attibute in конфигурация корневой узел):

перед: <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">

после: <configuration>