your programing

Web Config Transform이 작동하지 않음

lovepro 2020. 10. 4. 12:56
반응형

Web Config Transform이 작동하지 않음


.NET MVC 3.0 응용 프로그램에서 다음 구성이 있습니다 appSettings.

web.config

<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.Debug.config

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

그리고 디버그 모드에서 응용 프로그램을 실행,하지만 내 SMTP 포트는 여전히에서 값을 복용 web.config하지 web.Debug.config.

누구든지이 구성에서 무엇이 잘못 될 수 있는지 제안 할 수 있습니까?


Web.config 변환은 게시 작업의 일부로 만 적용됩니다.

당신이이의 일환으로 수행하려면 app.config: XML의 변환 비주얼 스튜디오 플러그인 - 빌드 작업, 당신은 SlowCheetah을 사용할 수 있습니다

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


Visual Studio (2010-2017) 는 불행히도 디버깅하는 동안 직접 지원 하지 않으며 게시 용으로 만 사용됩니다. 확장 SlowCheetah (표시된 답변)를 사용하더라도 저에게는 작동하지 않습니다 (app.config를 사용하는 프로젝트에서만 web.config).

참고 이 있음을 해결 CodeProject의에 설명 .

현재 web.config를 변환 된 버전으로 덮어 쓰도록 .msproj 파일을 수정하는 방법을 설명합니다.

먼저 해당 해결 방법을 옵션 1 로 설명 하지만 최근 에 사용하기 더 쉬운 다른 옵션 2를 발견했습니다 (원하는 경우 옵션 2로 직접 스크롤 할 수 있음).


옵션 1 : 원본 코드 프로젝트 문서 (위 링크 참조) 에서 가져온 지침을 추가했습니다 . 스크린 샷이 이미 사라졌기 때문에 전체 정보를 잃고 싶지 않기 때문입니다.

VS.Net은 로컬 환경을 개발하고 디버깅 할 때 변환을 수행하지 않습니다. 그러나 원하는 경우이를 수행하기 위해 수행 할 수있는 몇 가지 단계가 있습니다.

  • 먼저 기본 디버그 및 릴리스가 수행하려는 작업에 충분하지 않다고 가정하고 VS.Net 에서 원하는 구성을 만듭니다 .
  • 사용자를 마우스 오른쪽 버튼으로 클릭하고 구성 변환 추가를web.config 선택 하면 정의 된 각 구성에 대한 종속 변환 구성이 생성됩니다.
  • 이제 이름 web.configweb.base.config.
  • web.config프로젝트에를 추가 하십시오. 빌드 할 때마다 덮어 쓰여지기 때문에 그 안에 무엇이 있는지는 중요하지 않지만 프로젝트의 일부를 원하므로 VS.Net"당신의 프로젝트가 디버깅을 위해 구성되지 않았습니다"라는 팝업을 표시 하지 않습니다. 쪽으로.
  • .csproj프로젝트 파일을 편집 TransformXml하고 AfterBuild 대상에 다음 작업을 추가합니다 . 여기 내가 변화 될 것입니다 볼 수 있습니다 web.base.config을 사용하여 파일을 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).

들어 비주얼 스튜디오 2017, 경로를 명명 스키마가 변경되었습니다 예를 들어, 엔터프라이즈 버전은 여기에 있습니다 : C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\VisualStudio\v15.0\Web.
전문가 버전의 Enterprise경우 경로에서 Professional. 미리보기 버전을 사용하는 경우 추가 2017Preview.

그것을 컴파일하고 .exe 파일을 디렉토리 (예 : C:\MyTools\.

사용법 : 빌드 후 이벤트 에서 사용할 수 있습니다 ( 프로젝트 속성 에서 빌드 이벤트 를 선택한 다음 빌드이벤트 명령 줄 편집 ). 명령 줄 매개 변수는 다음과 같습니다 (예제).

"C : \ MyTools \ TransformConfig.Exe"/d:Web.config /t:Web.$(ConfigurationName).config /s:Web.Template.config / b : "$ (ProjectDir) \"

즉, 먼저 구성 파일의 이름, 변환 구성 파일, 선택적 템플릿 구성, 두 파일이 모두 포함 된 프로젝트의 경로가 뒤 따릅니다.

선택 사항 인 템플릿 구성 매개 변수를 추가했습니다. 그렇지 않으면 원래의 전체 구성이 변환에 의해 덮어 써지며, 이는 템플릿을 제공하여 피할 수 있습니다.

원본 Web.config를 복사하여 템플릿을 만들고 이름을 Web.Template.config로 지정합니다.

노트 :

  • 원하는 경우 TransformConfig.exe파일을 위에서 언급 한 Visual Studio 경로에 복사 Microsoft.Web.XmlTransform.dll하여 구성을 변환해야하는 모든 프로젝트에서 참조 할 수도 있습니다.

  • 내가 Environment.ExitCode = x;할당을 추가 한 이유를 궁금해하는 분들을 위해 : Main에서 단순히 int를 반환하는 것은 빌드 이벤트에 도움이되지 않았습니다. 자세한 내용은 여기를 참조 하세요.

  • 프로젝트를 게시하고 Web.Template.config를 사용하는 경우 게시하기 전에 올바른 구성 (일반적으로 릴리스)으로 솔루션 에서 다시 빌드 했는지 확인합니다 . 그 이유는 디버깅 중에 Web.Config를 덮어 쓰고 그렇지 않으면 잘못된 파일을 변환하게 될 수 있기 때문입니다.


Answering your question isn't simple, because it poses a problem - if you want to transform Web.config with Web.debug.config - where transformation effect should be stored? In Web.config itself? This would overwrite transformation source file! Probably that's why Visual Studio doesn't do transformations during builds.

Previous Matt answer is valid, but you might want to mix them to have generic solution that works when you actually change active solution configuration from debug to release etc. Here's a simple solution:

  1. Create your config transformations for configurations (Debug, Release, etc)
  2. Rename Web.config file to Web.base.config - transformations should automaticly rename accordingly (Web.base.Debug.config, etc)
  3. Add following transformWebConfig.proj XML file to your project folder:
<?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. Navigate to your project properties, choose Build Events and add following content to Post-build event command line:
@if exist "%ProgramFiles(x86)%\MSBuild\12.0\bin" set PATH=%ProgramFiles(x86)%\MSBuild\12.0\bin;%PATH%
msbuild $(ProjectDir)transformWebConfig.proj /t:TransformWebConfig /p:CurrentConfig=$(ConfigurationName) /p:TargetProjectName=$(TargetPath)

Now, when you build your solution, a Web.config file will be created with valid transformations for active configuration.


Your immediate question has been answered - the explanation is that the transform is applied on publish, not on build.

However, I think that it does not offer a solution on how to achieve what you want to do.

I have been struggling with this exact problem for a few days now, looking for a way to keep web.config clean and set all keys that vary depending on environment in the respective transform files. My conclusion is that the easiest and most stable solution is to use debug values in the original web.config, that way they are always present when you do debug runs in Visual Studio.

Then create transforms for the different environments you want to publish to - test, integration, production - whatever you have. The now built-in functionality to transform web.config files on publish will suffice for this. No need for SlowCheetah or editing build events nor project files. If you have only web projects that is.

Should you wish to, you could also have the web.debug.config file in your solution, just to keep a separate file with all the values pertaining to the development environment. Be sure to comment in it that the values are not applied when running in Visual Studio though, in case someone else try to use it for that purpose!


for VS 2017 I found the answer here not sure why nobody has referenced it above as it appears to be a very popular solution. Very easy too. Make sure you see the comment from IOrlandoni on Mar5 2019 for making it work in VS 2017 and all versions.

Basically its a two stepper. First, you edit the .csproj file, appending the code below. Second, you create a new web.base.config configuration and copy the existing web.config there. After doing that any build will overwrite your web.config with your desired transformation.

    <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\WebApplications\Microsoft.WebApplication.targets" />
<Target Name="BeforeBuild">
  <TransformXml Source="Web.Base.config" Transform="Web.$(Configuration).config" Destination="Web.config" />
</Target>  

Use Octopus Deploy (Community edition is free) and let it transform the web.config for you. Steps:

  1. Set up Octopus to deploy your web application
  2. Make sure your Web.Release.config has the Build Action property set to Content just like your main web.config file.

That's it! Octopus will do the rest without any special config. A default IIS Web Site deploy will do this out of the box:enter image description here


Apparently there's a extension for Visual Studio 2015

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

This package enables you to transform your app.config or any other XML file based on the build configuration


Recently I had the same problem with a older web.config filed based on .NET Framework 2.0. The solution was simply remove the web.config's namespace (xmlns attibute in configuration root node):

BEFORE: <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">

AFTER: <configuration>

참고URL : https://stackoverflow.com/questions/8841075/web-config-transform-not-working

반응형