W aplikacji .NET MVC 3.0 mam następującą konfigurację w appSettings
:
web.config
<appSettings>
<add key="SMTPHost" value="mail.domain.com"/>
<add key="SMTPUsername" value="[email protected]"/>
<add key="SMTPPort" value="25"/>
<add key="SMTPPwd" value="mypassword"/>
<add key="EmailFrom" value="[email protected]"/>
</appSettings>
Do debugowania mam zdefiniowaną następującą transformację konfiguracji:
web.Debug.config
<appSettings>
<add key="SMTPPort" value="58" xdt:Transform="Replace" xdt:Locator="Match(key)" />
</appSettings>
Uruchamiam aplikację w trybie debugowania, ale mój port SMTP nadal pobiera wartość z pliku web.config
, nie web.Debug.config
.
Czy ktoś może podpowiedzieć, co może być nie tak w tej konfiguracji?
Visual Studio (2010-2019) niestety nie obsługuje go bezpośrednio podczas debugowania, jest przeznaczony tylko do publikacji - nawet z rozszerzeniem SlowCheetah (zaznaczona odpowiedź) nie działa dla mnie (tylko dla projektów korzystających z app.config zamiast web.config).
Zauważ, że istnieje obejście opisane w codeproject .
Opisuje, jak zmodyfikować plik .msproj, aby nadpisać bieżący plik web.config przekształconą wersją.
Najpierw opiszę to obejście jako opcję 1 , ale niedawno odkryłem inną opcję 2 , która jest łatwiejsza w użyciu (więc możesz przewinąć bezpośrednio w dół do opcji 2, jeśli chcesz):
Opcja 1: Dodałem instrukcje zaczerpnięte z oryginalnego artykułu codeproject (patrz link powyżej), ponieważ zrzuty ekranów już tam nie ma, a nie chcę stracić całej informacji:
VS.Net nie dokonuje żadnych zmian podczas programowania i debugowania lokalnego środowiska. Ale jest kilka kroków, które możesz zrobić, aby tak się stało, jeśli chcesz.
web.config
i wybierz Dodaj konfigurację transformacji - spowoduje to utworzenie zależnej konfiguracji transformacji dla każdej zdefiniowanej konfiguracji.web.config
naweb.base.config
.web.config
do swojego projektu. Nie ma znaczenia, co w niej jest, ponieważ będzie nadpisany za każdym razem robimy build ale chcemy to część projektu tak VS.Net nie dają nam „Twój projekt nie jest skonfigurowany do debugowania” Pop- w górę..csproj
plik projektu i dodaj następująceTransformXml
zadanie do elementu docelowego AfterBuild. Tutaj możesz zobaczyć, że będę przekształcałweb.base.config
plik przy użyciuweb.[configuration].config
i zapisze go jakoweb.config
. Aby uzyskać szczegółowe informacje, proszę sprawdzić to Microsoft Q & A, i instrukcje Jak przedłużyć build, spójrz tam .Opcja 2:
Na podstawie tej odpowiedzi opracowałem prostą aplikację konsolową TransformConfig.exe (w składni 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); } } }
Upewnij się, że dodano bibliotekę DLL
"C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.XmlTransform.dll"
jako odwołanie (ten przykład dotyczy programu VS 2015, w przypadku starszych wersji należy zastąpićv14.0
w ścieżce odpowiedni numer wersji, npv11.0
.).Dla Visual Studio 2017, schemat nazewnictwa dla ścieżki nie zmieniło: Na przykład dla wersji Enterprise jest tutaj:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\VisualStudio\v15.0\Web
.Zakładam, że dla wersji profesjonalnej trzeba
Enterprise
w ścieżce wymienić wgProfessional
. Jeśli używasz wersji zapoznawczej, dodatkowo zamień2017
naPreview
.Oto omówienie, jak zmieniła się ścieżka dla różnych wersji programu Visual Studio (jeśli nie masz wersji Enterprise, może być konieczne zastąpienie
Enterprise
przezProfessional
w ścieżce):Skompiluj go i umieść plik .exe w katalogu np
C:\MyTools\
.Użycie: Możesz go użyć w zdarzeniu po kompilacji (we właściwościach projektu wybierz Zdarzenia kompilacji , a następnie edytuj wiersz poleceń zdarzenia po kompilacji ). Parametry wiersza poleceń to (przykład):
tj. najpierw nazwa pliku konfiguracyjnego, następnie plik konfiguracyjny transformacji, następnie opcjonalna konfiguracja szablonu, a następnie ścieżka do projektu zawierającego oba pliki.
Dodałem opcjonalny parametr konfiguracji szablonu, ponieważ w przeciwnym razie oryginalna kompletna konfiguracja zostałaby nadpisana przez transformację, czego można uniknąć, udostępniając szablon.
Utwórz szablon, po prostu kopiując oryginalny plik Web.config i nadaj mu nazwę Web.Template.config.
Uwaga:
Jeśli wolisz, możesz również skopiować
TransformConfig.exe
plik do wspomnianej powyżej ścieżki programu Visual Studio, w którejMicrosoft.Web.XmlTransform.dll
znajduje się plik, i odwoływać się do niego we wszystkich projektach, w których musisz przekształcić konfiguracje.Dla tych z Was, którzy zastanawiają się, dlaczego dodałem
Environment.ExitCode = x;
zadania: Zwrócenie int z Main nie pomogło w zdarzeniu kompilacji. Zobacz szczegóły tutaj.Jeśli publikujesz swój projekt i używasz pliku Web.Template.config, upewnij się, że przed opublikowaniem dokonałeś przebudowy rozwiązania z odpowiednią konfiguracją (zwykle Release). Powodem jest to, że plik Web.Config jest nadpisywany podczas debugowania iw przeciwnym razie może skończyć się przekształceniem niewłaściwego pliku.
źródło
Odpowiedź na twoje pytanie nie jest prosta, ponieważ stwarza problem - jeśli chcesz przekształcić Web.config za pomocą Web.debug.config - gdzie powinien być przechowywany efekt transformacji? W samym Web.config? Spowoduje to nadpisanie pliku źródłowego transformacji! Prawdopodobnie dlatego Visual Studio nie wykonuje transformacji podczas kompilacji.
Poprzednia odpowiedź Matta jest prawidłowa, ale możesz chcieć je wymieszać, aby uzyskać ogólne rozwiązanie, które działa, gdy faktycznie zmienisz konfigurację aktywnego rozwiązania z debugowania na wydanie itp. Oto proste rozwiązanie:
Web.config
pliku naWeb.base.config
- transformacje powinny automatycznie odpowiednio zmienić nazwę (Web.base.Debug.config
itp.)<?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>
Teraz podczas budowania rozwiązania zostanie utworzony plik Web.config z poprawnymi przekształceniami dla aktywnej konfiguracji.
źródło
'"$(MSBuildBinPath)\msbuild.exe" $(ProjectDir)TransformWebConfig.proj /t:TransformWebConfig /p:CurrentConfig=$(ConfigurationName) /p:TargetProjectName=$(TargetPath)
i zaktualizowałemv12.0
dov14.0
w pliku .proj.12.0
do14.0
w przypadku VS 2017 znalazłem tutaj odpowiedź , nie jestem pewien, dlaczego nikt nie wspomniał o niej powyżej, ponieważ wydaje się, że jest to bardzo popularne rozwiązanie. Bardzo łatwe. Upewnij się, że widzisz komentarz IOrlandoni z 5 marca 2019 r., Aby działał w VS 2017 i we wszystkich wersjach.
Zasadniczo jest to dwustopniowy. Najpierw edytuj plik .csproj, dołączając poniższy kod. Po drugie, tworzysz nową konfigurację web.base.config i kopiujesz tam istniejący web.config. Po wykonaniu tej czynności każda kompilacja nadpisze plik web.config żądaną transformacją.
<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>
źródło
Web.config
zContent
naNone
, możesz użyćSource="Web.config" Destination="$(TargetPath).config"
(lub być może w przypadku niektórych typów projektówDestination="$(TargetDir)Web.config"
). Przeniosłem również przekształcenie doAfterBuild
, ponieważ nie trzeba już tego robić przed skopiowaniem plików.bin
.Odpowiedź na Twoje bezpośrednie pytanie została udzielona - wyjaśnienie jest takie, że transformacja jest stosowana podczas publikowania, a nie kompilacji.
Uważam jednak, że nie oferuje rozwiązania tego, jak osiągnąć to, co chcesz.
Od kilku dni zmagam się z tym właśnie problemem, szukając sposobu na utrzymanie porządku w pliku web.config i ustawienie wszystkich kluczy, które różnią się w zależności od środowiska w odpowiednich plikach transformacji. Mój wniosek jest taki, że najłatwiejszym i najbardziej stabilnym rozwiązaniem jest użycie wartości debugowania w oryginalnym pliku web.config, dzięki czemu są one zawsze obecne podczas debugowania uruchomień w programie Visual Studio.
Następnie utwórz transformacje dla różnych środowisk, w których chcesz publikować - testowanie, integracja, produkcja - cokolwiek masz. Do tego wystarczy wbudowana funkcja przekształcania plików web.config podczas publikowania. Nie ma potrzeby używania SlowCheetah ani edytowania wydarzeń kompilacji ani plików projektów. Jeśli masz tylko projekty internetowe, to znaczy.
Jeśli chcesz, możesz również mieć w swoim rozwiązaniu plik web.debug.config, aby zachować oddzielny plik ze wszystkimi wartościami dotyczącymi środowiska programistycznego. Pamiętaj, aby skomentować w nim, że wartości nie są stosowane podczas uruchamiania w programie Visual Studio, na wypadek, gdyby ktoś inny próbował go użyć do tego celu!
źródło
Użyj Octopus Deploy (edycja społecznościowa jest bezpłatna) i pozwól jej przekształcić
web.config
za Ciebie. Kroki:Web.Release.config
, żeBuild Action
właściwość jest ustawionaContent
tak, jak w przypadkuweb.config
pliku głównego .Otóż to! Octopus zrobi resztę bez specjalnej konfiguracji. Domyślne wdrożenie w witrynie sieci Web usług IIS wykona to po wyjęciu z pudełka:
źródło
Najwyraźniej istnieje rozszerzenie dla programu Visual Studio 2015
https://visualstudiogallery.msdn.microsoft.com/05bb50e3-c971-4613-9379-acae2cfe6f9e
Ten pakiet umożliwia przekształcenie pliku app.config lub dowolnego innego pliku XML na podstawie konfiguracji kompilacji
źródło
new
świat jako zdanie.Ostatnio miałem ten sam problem ze starszym plikiem web.config opartym na .NET Framework 2.0. Rozwiązaniem było po prostu usunięcie przestrzeni nazw web.config ( atrybut xmlns w węźle głównym konfiguracji ):
PRZED:
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
PO:
<configuration>
źródło