Web Config Transform çalışmıyor


88

Bir .NET MVC 3.0 Uygulamasında aşağıdaki yapılandırmaya sahibim 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>

Hata ayıklama için aşağıdaki yapılandırma dönüşümünü tanımladım:

web.Debug.config

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

Ve hata ayıklama modunda uygulamayı çalıştırmak ama benim SMTP portu hala değeri alıyor web.config, değil web.Debug.config.

Bu konfigürasyonda neyin yanlış olabileceğini kimse önerebilir mi?

Yanıtlar:


157

Web.config dönüşümleri yalnızca bir yayınlama işleminin parçası olarak uygulanır.

Bunun bir app.configderleme işleminin parçası olarak yapılmasını istiyorsanız, SlowCheetah - XML ​​Transforms Visual Studio eklentisini kullanabilirsiniz:

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


1
Bana çok zaman kazandırdığın için çok teşekkür ederim.
HaBo

3
vay bu cevabı bulmam 2 saatimi aldı. Gönderdiğin için teşekkürler, saçımı çekiyor olurdum.
Peanut

Görünüşe göre Visual Studio 2015'te (Web) .config dönüşümleri artık yerleşik bir özelliktir, dolayısıyla artık SlowCheetah'a ihtiyacınız yoktur. Ancak yerleşik dönüşümler, çalıştırırsanız değil, yalnızca uygulamayı yayınlarsanız geçerli olur. Nasıl çözdüğüme buradan bakabilirsiniz .
Matt

1
@ Komsky'nin cevabı basit ve temiz bir çözüm sunarken, bunu neden kullanacağınızdan emin değilim.
Csaba Toth

2
SlowCheetah harika, ancak kendi belgelerine göre: "Web projeleri için, uygulamanızı yayınladığınızda veya paketlediğinizde dosyalar dönüştürülür." Başka bir deyişle, hata ayıklama sırasında değil.
Doug

33

Visual Studio (2010 - 2019) , siz hata ayıklarken maalesef bunu doğrudan desteklemiyor, yalnızca yayınlama amaçlıdır - SlowCheetah (işaretli yanıt) uzantısıyla bile benim için çalışmıyor (yalnızca app.config kullanan projeler için web.config).

Bir çözüm olduğunu unutmayın . CodeProject adresinde açıklanan .

Dönüştürülen sürümün geçerli web.config dosyasının üzerine yazmak için .msproj dosyasının nasıl değiştirileceğini açıklar.

İlk önce bu geçici çözümü Seçenek 1 olarak tanımlayacağım , ancak yakın zamanda kullanımı daha kolay olan başka bir Seçenek 2 buldum (bu nedenle isterseniz doğrudan 2. seçeneğe kaydırabilirsiniz):


Seçenek 1: Orijinal kod projesi makalesinden alınan talimatları ekledim (yukarıdaki bağlantıya bakın), çünkü oradaki ekran görüntüleri çoktan gitti ve tüm bilgileri kaybetmek istemiyorum:

VS.Net, yerel ortamınızı geliştirirken ve yalnızca hata ayıklarken herhangi bir dönüştürme yapmaz. Ancak, isterseniz bunu gerçekleştirmek için yapabileceğiniz bazı adımlar var.

  • Öncelikle, varsayılan hata ayıklama ve yayınlamanın başarmaya çalıştığınız şey için yeterli olmadığını varsayarak VS.Net'te istediğiniz yapılandırmaları oluşturun .
  • Sağ tıklayın web.configve Yapılandırma Dönüşümleri Ekle'yi seçin - bu, tanımlanan her bir yapılandırmanız için bağımlı bir dönüşüm yapılandırması oluşturacaktır.
  • Artık yeniden adlandırabilirsiniz web.configTo web.base.config.
  • web.configProjenize bir ekleyin . İçinde ne olduğu önemli değil çünkü her derleme yaptığımızda üzerine yazılacak, ancak projenin bir parçası olmasını istiyoruz, böylece VS.Net bize "Projeniz Hata Ayıklama için yapılandırılmamış" vermiyor açılır penceresini yukarı.
  • Düzenleyin .csprojProje Dosyası ve aşağıdakileri ekleyin TransformXmlAfterBuild hedefe görevi. Burada ben dönüştüren olacak görebilirsiniz web.base.configkullanarak dosyayı web.[configuration].configve olarak kaydeder web.config. Ayrıntılar için lütfen bu Microsoft Soru ve Cevap bölümüne bakın ve yapının nasıl genişletileceğine ilişkin talimatlar için oraya bakın .

Seçenek 2:

Bu cevaba dayanarak, basit bir konsol uygulaması geliştirdim, TransformConfig.exe (C # 6.0 sözdiziminde):

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'yi "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.XmlTransform.dll"referans olarak eklediğinizden emin olun (bu örnek VS 2015 için geçerlidir, eski sürümler v14.0için yolu uygun sürüm numarasıyla değiştirin, örn.v11.0 ).

İçin Visual Studio 2017, yol için adlandırma şeması değişti: Örneğin, kurumsal versiyonu için o burada: C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\VisualStudio\v15.0\Web.
Profesyonel sürüm Enterpriseiçin yolu değiştirmeniz gerektiğini varsayıyorum Professional. Önizleme sürümünü kullanıyorsanız, ayrıca değiştirin 2017tarafından Preview.

Burada yol (Enterprise sürümü yoksa değiştirmek gerekebilir Visual Studio farklı sürümleri için nasıl değiştiğini genel bir bakış Enterpriseile Professionalyolunda):

VS Sürüm         Yolu (için Microsoft.Web.XmlTransform.dll)
2015                   C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\Web
2017                   C:\Program Files (x86)\Microsoft Visual Studio\2017\
                          Enterprise\MSBuild\Microsoft\VisualStudio\v15.0\Web
2019                  C:\Program Files (x86)\Microsoft Visual Studio\2019\
                          Enterprise\MSBuild\Microsoft\VisualStudio\v16.0\Web

Derleyin ve .exe dosyasını bir dizine koyun, örn C:\MyTools\.

Kullanım: Bunu, derleme sonrası olayınızda kullanabilirsiniz ( proje özelliklerinde , Olayları Oluştur'u seçin , ardından Oluşturma sonrası olay komut satırını düzenleyin ). Komut satırı parametreleri (örnek):

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

ör. önce yapılandırma dosyasının adı, ardından dönüştürme yapılandırma dosyası, ardından isteğe bağlı bir şablon yapılandırması, ardından her iki dosyayı da içeren projenizin yolu.

İsteğe bağlı şablon yapılandırma parametresini ekledim, çünkü aksi takdirde orijinal tam yapılandırmanızın üzerine dönüşüm tarafından yazılır, bu da bir şablon sağlayarak önlenebilir.

Şablonu, orijinal Web.config dosyasını kopyalayıp Web.Template.config olarak adlandırarak oluşturun.

Not:

  • Tercih ederseniz, TransformConfig.exedosyayı yukarıda belirtilen Visual Studio yoluna da kopyalayabilir ve Microsoft.Web.XmlTransform.dllyapılandırmalarınızı dönüştürmeniz gereken tüm projelerinizde buna başvurabilirsiniz.

  • Neden Environment.ExitCode = x;atamalar eklediğimi merak edenler için : Basitçe Main'den int döndürmek, build olayına yardımcı olmadı. Ayrıntıları burada görün .

  • Projenizi yayınlıyorsanız ve bir Web.Template.config kullanıyorsanız, yayınlamadan önce çözümünüzde doğru yapılandırmayla (genellikle Sürüm) yeniden oluşturduğunuzdan emin olun. Bunun nedeni, hata ayıklama sırasında Web.Config'in üzerine yazılması ve aksi takdirde yanlış dosyayı dönüştürmenizdir.


1
Görünüşe göre CodeProject gönderisi pooched. Kod örnekleri için ekran görüntüleri kullandı ve şimdi blogu çöktüğü için tarihin içinde kayboldular.
Eric Lloyd

3
Evet, maalesef ekran görüntüleri gitti. Ama en azından makale metni hala orada ve yaklaşımı açıklıyor. Kaybetmemek için cevabıma metin açıklamasını ekledim.
Matt

1
Doğru, belki orada düzeltmek için codeproject'den yazar James Coleman ile iletişime geçmeye çalışabilirsiniz. Yine de orada hala aktif olup olmadığından emin değilim. @ThomasTeilmann
Matt

Bunun kayıp ekran görüntülerinde olanlara benzer olabileceğini düşünüyorum. Aynı temel sonucu elde ediyor gibi görünüyor. stackoverflow.com/a/6437192/1003916
user1003916

22

Sorunuzu yanıtlamak basit değildir, çünkü bir sorun teşkil eder - Web.config'i Web.debug.config ile dönüştürmek istiyorsanız - dönüşüm etkisinin nerede depolanması gerekir? Web.config'in kendisinde mi? Bu, dönüşüm kaynak dosyasının üzerine yazacaktır! Muhtemelen bu yüzden Visual Studio derlemeler sırasında dönüşümler yapmaz.

Önceki Matt cevabı geçerlidir, ancak bunları, aktif çözüm yapılandırmasını hata ayıklamadan yayına değiştirdiğinizde çalışan genel bir çözüme sahip olacak şekilde karıştırmak isteyebilirsiniz. İşte basit bir çözüm:

  1. Konfigürasyonlar için konfigürasyon dönüşümlerinizi oluşturun (Hata Ayıklama, Yayın, vb.)
  2. Web.configDosyayı şu şekilde yeniden adlandır Web.base.config- dönüşümler buna göre otomatik olarak yeniden adlandırılmalıdır ( Web.base.Debug.configvb.)
  3. Proje klasörünüze aşağıdaki transformWebConfig.proj XML dosyasını ekleyin:
<?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. Proje özelliklerinize gidin, Olay Oluştur'u seçin ve derleme sonrası olay komut satırına aşağıdaki içeriği ekleyin :
@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)

Şimdi, çözümünüzü oluşturduğunuzda, etkin yapılandırma için geçerli dönüştürmelerle bir Web.config dosyası oluşturulacaktır.


En temiz ve en iyi cevap. Bazı sorular: 1. XML doğrulamaları neden TransformXml öğesinin Hedef öğe içinde geçersiz olduğunu söylüyor? (yapı BTW'de çalışıyor). 2. Artık bu gerçek Web.Config'i oluşturduğuna göre, yine de projeye Web.Config'i ekliyorum. Şimdi Debug / Release arasında her geçiş yaptığımda web.config değişecek, ancak bunu her zaman kaynak depoya dahil etmek istemiyorum.
Csaba Toth

1. VS'nin bu XML'i şemayla nasıl doğruladığını tam olarak söyleyemem, ancak bu uyarı yaygındır, bu nedenle onu yok sayabilirsiniz. 2. Kullandığınız depoya bağlıdır, ancak örneğin git.ignore dosya girişini kullanabilirsiniz.
komsky

4
Bu benim için iyi çalıştı - sadece build-event ve project dosyasındaki 12'leri mevcut sürüme değiştirdim. Post-build olay için kullandığım: '"$(MSBuildBinPath)\msbuild.exe" $(ProjectDir)TransformWebConfig.proj /t:TransformWebConfig /p:CurrentConfig=$(ConfigurationName) /p:TargetProjectName=$(TargetPath) ve güncelleştirilmiş v12.0için v14.0.proj dosyasında.
Jovie

1
VS 2017 için her 12.0birini şu şekilde değiştirin14.0
Csaba Toth

1
1) oluşturulan web.config dosyasını web projesine eklemeyi unutmayın, aksi takdirde yayınlandıktan sonra hedef klasöre kopyalanmayacaktır. 2) derleme sunucusunda bu iki dosya yoksa, onları "Microsoft.Web.Publishing.Tasks", "Microsoft.Web.XmlTransform"
phiree

8

VS 2017 için cevabı burada buldum kimse çok popüler bir çözüm olarak göründüğü gibi yukarıdaki bunu başvurulan neden değil emin olun. Çok da kolay. VS 2017 ve tüm sürümlerde çalışmasını sağlamak için 5 Mart 2019'da IOrlandoni'nin açıklamasını gördüğünüzden emin olun.

Temelde iki kademeli. İlk olarak, aşağıdaki kodu ekleyerek .csproj dosyasını düzenleyin. İkinci olarak, yeni bir web.base.config yapılandırması oluşturursunuz ve var olan web.config'i oraya kopyalarsınız. Bunu yaptıktan sonra herhangi bir yapı, istediğiniz dönüşümü web.config'inizin üzerine yazacaktır.

<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>  

Muhtemelen en iyi cevap bu, ancak IMO'da bir numara eksik. Eğer değiştirirseniz Web.configgelen Contentiçin Noneo zaman kullanabilirsiniz Source="Web.config" Destination="$(TargetPath).config"(, projenin bazı türleri için ya da belki Destination="$(TargetDir)Web.config"). AfterBuildDosyalar kopyalanmadan önce artık yapılması gerekmediğinden dönüşümü konumuna da taşıdım .
Peter Taylor

Tamam, aslında bu işe yaramıyor çünkü bazı nedenlerden dolayı çalışacak şekilde yapılandıramıyorum bin.
Peter Taylor

5

Anlık sorunuz yanıtlandı - açıklama, dönüşümün yapıda değil, yayınlanırken uygulandığı yönündedir.

Ancak, yapmak istediğiniz şeye nasıl ulaşacağınız konusunda bir çözüm sunmadığını düşünüyorum.

Web.config'i temiz tutmanın ve ilgili dönüştürme dosyalarındaki ortama bağlı olarak değişen tüm anahtarları ayarlamanın bir yolunu arıyorum, bu problemle birkaç gündür uğraşıyorum. Sonuç olarak, en kolay ve en kararlı çözüm, orijinal web.config içindeki hata ayıklama değerlerini kullanmaktır, bu şekilde Visual Studio'da hata ayıklama çalıştırmaları yaptığınızda her zaman mevcut olurlar.

Ardından, yayınlamak istediğiniz farklı ortamlar için (test, entegrasyon, üretim) dönüşümler oluşturun. Yayın sırasında web.config dosyalarını dönüştürmek için artık yerleşik işlevsellik bunun için yeterli olacaktır. SlowCheetah'a veya derleme olaylarını veya proje dosyalarını düzenlemeye gerek yok. Yalnızca web projeleriniz varsa.

Dilerseniz, geliştirme ortamıyla ilgili tüm değerleri içeren ayrı bir dosya tutmak için çözümünüzde web.debug.config dosyasını da bulundurabilirsiniz. Bir başkasının bu amaçla kullanmaya çalışması durumunda, Visual Studio'da çalışırken değerlerin uygulanmadığını yorumladığınızdan emin olun!


1

Octopus Deploy'u kullanın (Topluluk sürümü ücretsizdir) ve web.configsizin için dönüştürmesine izin verin . Adımlar:

  1. Web uygulamanızı dağıtmak için Octopus'u kurun
  2. Emin olun sizin Web.Release.configsahiptir Build Actionmülk seti Contentsadece ana gibi web.configdosyada.

Bu kadar! Ahtapot, gerisini herhangi bir özel yapılandırma olmadan halleder. Varsayılan bir IIS Web Sitesi dağıtımı, bunu kutudan çıkarır:görüntü açıklamasını buraya girin


2 numara anahtardır :)
Reza

0

Görünüşe göre Visual Studio 2015 için bir uzantı var

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

Bu paket, uygulama yapılandırmanızı temel alarak app.config dosyanızı veya diğer herhangi bir XML dosyasını dönüştürmenize olanak tanır


SlowCheeta yeni değil. uzun zamandır oradaydı. 1.1 sürümleri
9/8/2011 tarihinde

@HaBo İlginiz için teşekkür ederim, newdünyayı cümle olarak çıkardım .
Amir Astaneh

0

Son zamanlarda .NET Framework 2.0 tabanlı eski bir web.config dosyasıyla aynı sorunu yaşadım . Çözüm, basitçe web.config ad alanını kaldırmaktı ( yapılandırma kök düğümündeki xmlns niteliği ):

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

SONRA: <configuration>

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.