Servus zusammen,
ich versuche ein ASP.Net Core Projekt so umzustellen, dass DB-Connectionstrings und API-Pfade aus der appconfig.json gelesen . Abhähig von der gewählten Konfiguration soll die appconfig.Development.json oder appconfig.Testserver.json (und noch ein paar weitere Konfiguratonen) gewählt werden.
Ich habe in der launchsettings.json mehrere Profile angelegt, die verschiedene Konfiguratonen "bedienen", beispielsweise:
"Development": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": "true",
"applicationUrl": "https://localhost:5001;http://localhost:5000"
}
Wenn ich nun lokal das Projekt mit "Development" starte, wird die korrekte appconfig gewählt. Soweit alles schön.
Nun veröffentliche ich mein Projekt per WebDeploy auf meinen IIS-Server, in den Einstellungen habe ich unter Configuration "Development" angegeben. Es wird allerdings immer die appsettings.json genutzt.
Mein HostBuilder:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddEnvironmentVariables();
var env = hostingContext.HostingEnvironment;
config.AddJsonFile($"appsettings.json", optional: false, reloadOnChange: true);
config.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
}
);
Wenn ich env.EnviromentName
auslese, ist es immer Production, klar dass dann die "falsche" appsettings.json genutzt wird.
Ich habe auf dem Server die Umgebungsvariablen ASPNETCORE_ENVIROMENT
und DOTNET_ENVIROMENT
(Hinweis auf GitHub) auf "Development" gesetzt, das hat allerdings nichts geändert.
Wo ist mein Fehler?
Danke schonmal!
Kriz
Eigentlich ist das Thema gut dokumentiert.
Schau mal ob du dort alles korrekt gemacht hast.
Doku:
https://learn.microsoft.com/de-de/aspnet/core/fundamentals/environments?view=aspnetcore-7.0
T-Virus
Developer, Developer, Developer, Developer....
99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
Führe den Hinweis unter "Windows: IIS-Bereitstellungen" dort aus, d.h. nach Ändern der Umgebungsvariablen starte den IIS (bzw. den ganzen Server) neu.
Wie T-Virus das korrekt sagt, ist das Konfigurationsleben eigentlich wirklich gut dokumentiert. Ist auch etwas, das man wirklich durchgelesen und nicht nur ausprobiert haben sollte, weil man ansonsten paar Sachen nicht versteht bzw. die Konzepte und Auswirkungen dahinter.
Gedacht ist es so, dass Dein Artifakt auf einem Server immer Production darstellt. Das Verhalten ist also absolut korrekt.
Development ist hier nicht der Stage-Name, sondern der Bezeichner, dass Du damit lokal entwickelst.
Das Problem aber an für sich existiert gar nicht, weil Du auf einem Server individuelle Einstellungen über die Umgebungsvariablen umsetzen solltest (zB Connection Strings) und nicht über die config.
Die Config ist hier im Endeffekt nur die Dokumentation, wie Deine Config-Struktur aussieht bzw. technische Defaults. Connection Strings und andere Stage-abhängige Settings gehören nicht zu Defaults.
Credentials und Connection Strings haben niemals was in Dateien zu suchen.
Daher gibts für die lokale Entwicklung auch die dotnet user secrets
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Zitat von Abt
Das Problem aber an für sich existiert gar nicht, weil Du auf einem Server individuelle Einstellungen über die Umgebungsvariablen umsetzen solltest (zB Connection Strings) und nicht über die config.
ConnectionsString in den Umgebungsvariablen hinterlegen? Hätte gedacht die sind eher für systemrelevante Sachen relevant... und nicht für ConnectionStrings einer Anwendung.
Die Lösung war übrigens der Publishdatei das Enviroment noch mit zu übergeben, das fehlte. Nun arbeitet es wie gewünscht. Danke nochmal an Th69 und T-Virus, manchmal sind es die offensichtlichen Sachen.
@Abt: Wenn nun aber die appconfig nicht für ConnectionStrings und Api-Pfade genutzt werden "soll", muss ich nun jedes mal beim Veröffentlichen einer Anwendung ein Batch laufen lassen, damit die nötigen Strings und Pfade in den Umgebungsvariablen eingetragen werden? Das wirkt mir etwas umständlich?!
Du hast gefragt, wie man "richtig" mit einer Config umgeht. Was Du nun hast ist halt ein Workaround, aber nicht "richtig".
Zitat von Kriz
ConnectionsString in den Umgebungsvariablen hinterlegen? Hätte gedacht die sind eher für systemrelevante Sachen relevant... und nicht für ConnectionStrings einer Anwendung.
Die Rückfrage zeigt, dass Du die Links, die Dir gegeben wurden, nicht angeschaut hast. Das ist echt schade, weil die Dir nicht zum Spaß gegeben wurden, sondern dass Du verstehst, warum man das so macht: zum Beispiel alleine aus Sicherheitsgründen.
Du sollst doch was dazu lernen, dann nimm doch die Hilfe an.
Zitat von Abt
Ist auch etwas, das man wirklich durchgelesen und nicht nur ausprobiert haben sollte, weil man ansonsten paar Sachen nicht versteht bzw. die Konzepte und Auswirkungen dahinter.
..is halt ein Konzeptthema. Wird schwer ohne zu lesen 😉
@Abt: Wenn nun aber die appconfig nicht für ConnectionStrings und Api-Pfade genutzt werden "soll", muss ich nun jedes mal beim Veröffentlichen einer Anwendung ein Batch laufen lassen, damit die nötigen Strings und Pfade in den Umgebungsvariablen eingetragen werden? Das wirkt mir etwas umständlich?!
Dir mag das umständlich wirken, weil Du halt quasi nichts automatisiert hast. In jeder Automatisierung, egal ob Azure, AWS, Google... und auch für OnPrem Automatismen gibt es eingebaute Lösungen dafür. Checkst Du Credentials oder Connection Strings zB in GitHub rein, weil Du leider sowas in einer Datei hinterlegt hast, bekommst Du auch eine Sicherheitswarnung - zurecht.
Du machst das halt manuell über Right Click Publish..., tjo...
Friends don't let friends right-click publish
Umgekehrt: Dein Workaround ist in echten Umgebungen - echt im Sinne wie "mehr als 1-Mann-Hobby" - mehr Aufwand, als einfach simple Umgebungsvariablen zu nutzen.
Du kannst Deinen Workaround (was anderes isses nicht) weiter machen, wenn Du das willst - aber der Weg, wie das Tooling gedacht ist, ist es halt nicht.
Und sicher auch nicht. Davon abgesehen hat man in den meisten Fällem beim Erstellen des Deployment Pakets noch keine Kenntnis über die Stage (dev, test, prod etc..). Daher ist es eine Grundregel in Automatismen/DevOps, dass Stage-Settings getrennt vom Artefakt behandelt werden.
DevOps würde schlicht und einfach nicht mal funktionieren.
Der einzige sichere Weg mit Credentials in der Config sind die Umgebungsvariablen, egal on in .NET, Java, Node.. egal ob auf Windows, Linux, Docker... oder - wenn die Umgebung das ermöglicht - noch besser spezielle Services wie Azure Key Vault.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Klasse, vielen Dank! Das hat mir alles schonmal gut weiter geholfen!
Wir sind eine 2-Mann Firma und ich bin der einzige Entwickler, da war es bist jetzt noch nicht so nötig CI/CD und unterschiedliche Umgebungen "professionell" aufzuziehen, aber am Ende des Tages ist es einfach nur sinnvoll es von Anfang an auch schon richtig anzugehen.
Ich werde mal versuchen mit GitHub Actions einen CI/CD Workflow zu erstellen, das scheint einer der wenigen Anbieter zu sein, die nicht sooo teuer sind.
Vielen Dank!
Kriz
Zitat von Kriz
Klasse, vielen Dank! Das hat mir alles schonmal gut weiter geholfen!
Wir sind eine 2-Mann Firma und ich bin der einzige Entwickler, da war es bist jetzt noch nicht so nötig CI/CD und unterschiedliche Umgebungen "professionell" aufzuziehen, aber am Ende des Tages ist es einfach nur sinnvoll es von Anfang an auch schon richtig anzugehen.
Das ist ein falscher Trugschluss.
Ein CI/CD Setup ist auch eine aktive Dokumentation, wie Software erstellt qualitativ erstellt wird. Es ist die Basis von Wissenstransfer.
In eurem Fall hängt offenbar alles von Dir ab, was für das Unternehmen dann ein Risiko darstellen würde.
Wie Damian im verlinkten Artikel auch schreibt, ist es auch als Solo-Developer super ratsam, sowas ausnahmslos immer aufzusetzen.
Ich werde mal versuchen mit GitHub Actions einen CI/CD Workflow zu erstellen, das scheint einer der wenigen Anbieter zu sein, die nicht sooo teuer sind.
GitHub Actions sind prinzipiell vollkommen kostenlos (2000 Build Minutes pro Monat).
Wenn man einen Custom Agent (eigene VM) hinterlegt, sogar dauerhaft.
Kosten sind also niemals eine Ausrede das nicht zu verwenden.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code