Was ich versuche: Ich versuche, die Azure App-Konfiguration mit einer .net Core 2.1 MVC-Webanwendung mit einem Sentinel-Schlüssel in der Azure App-Konfiguration einzurichten, mit dem Ziel, Schlüssel in Azure und keinen der Schlüssel ändern zu können wird in meinen Apps aktualisiert, bis sich der Sentinel-Wert geändert hat. Theoretisch sollte dies mir ermöglichen, Konfigurationen sicher im laufenden Betrieb auszutauschen.
Was mein Problem ist: Wenn ich dies tue, ist keine WatchAndReloadAll () -Methode verfügbar, um den Sentinel im IWebHostBuilder zu überwachen, und die alternativen Refresh () -Methoden scheinen die Konfiguration nicht so zu aktualisieren, wie sie angeben.
Hintergrundinformationen und was ich versucht habe: Ich habe letzte Woche an VS Live - San Diego teilgenommen und mir eine Demo zur Azure App-Konfiguration angesehen. Ich hatte einige Probleme beim Versuch, die Anwendung dazu zu bringen, Konfigurationswerte zu aktualisieren, als ich sie implementierte. Daher habe ich auch auf diese Demo verwiesen, in der beschrieben wurde, wie dies ebenfalls funktioniert. Der entsprechende Abschnitt befindet sich in ungefähr 10 Minuten. Diese Methode scheint jedoch im IWebHostBuilder nicht verfügbar zu sein.
Dokumentation, auf die ich verweise: In der offiziellen Dokumentation gibt es keinen Verweis auf diese Methode, siehe doc quickstart .net core und doc dynamic configuration .net core
Meine Umgebung: Verwenden von dot net core 2.1 unter Visual Studio Enterprise 2019 mit dem neuesten Preview-Nuget-Paket für Microsoft.Azure.AppConfiguration.AspNetCore 2.0.0-Preview-010060003-1250
Mein Code: In der Demo haben sie einen IWebHostBuilder über die CreateWebHostBuilder-Methode (string [] args) wie folgt erstellt:
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
return WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
var settings = config.Build();
config.AddAzureAppConfiguration(options =>
{
options.Connect(settings["ConnectionStrings:AzureConfiguration"])
.Use(keyFilter: "TestApp:*")
.WatchAndReloadAll(key: "TestApp:Sentinel", pollInterval: TimeSpan.FromSeconds(5));
});
})
.UseStartup<Startup>();
}
Ich habe es auch so versucht, indem ich die aktuelle Dokumentation verwendet habe:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
var settings = config.Build();
config.AddAzureAppConfiguration(options =>
{
// fetch connection string from local config. Could use KeyVault, or Secrets as well.
options.Connect(settings["ConnectionStrings:AzureConfiguration"])
// filter configs so we are only searching against configs that meet this pattern
.Use(keyFilter: "WebApp:*")
.ConfigureRefresh(refreshOptions =>
{
// In theory, when this value changes, on the next refresh operation, the config will update all modified configs since it was last refreshed.
refreshOptions.Register("WebApp:Sentinel", true);
refreshOptions.Register("WebApp:Settings:BackgroundColor", false);
refreshOptions.Register("WebApp:Settings:FontColor", false);
refreshOptions.Register("WebApp:Settings:FontSize", false);
refreshOptions.Register("WebApp:Settings:Message", false);
});
});
})
.UseStartup<Startup>();
Dann in meiner Startklasse:
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<Settings>(Configuration.GetSection("WebApp:Settings"));
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseAzureAppConfiguration();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
und schließlich mein Einstellungskonfigurationsmodell:
public class Settings
{
public string BackgroundColor { get; set; }
public long FontSize { get; set; }
public string FontColor { get; set; }
public string Message { get; set; }
}
Jetzt ziehe ich in meinem Controller diese Einstellungen und werfe sie in eine Ansichtstasche, um sie in der Ansicht anzuzeigen.
public class HomeController : Controller
{
private readonly Settings _Settings;
public HomeController(IOptionsSnapshot<Settings> settings)
{
_Settings = settings.Value;
}
public IActionResult Index()
{
ViewData["BackgroundColor"] = _Settings.BackgroundColor;
ViewData["FontSize"] = _Settings.FontSize;
ViewData["FontColor"] = _Settings.FontColor;
ViewData["Message"] = _Settings.Message;
return View();
}
}
Eine einfache Ansicht zum Anzeigen der Änderungen:
<!DOCTYPE html>
<html lang="en">
<style>
body {
background-color: @ViewData["BackgroundColor"]
}
h1 {
color: @ViewData["FontColor"];
font-size: @ViewData["FontSize"];
}
</style>
<head>
<title>Index View</title>
</head>
<body>
<h1>@ViewData["Message"]</h1>
</body>
</html>
Ich kann es dazu bringen, die Konfiguration beim ersten Mal herunterzuziehen, aber die Aktualisierungsfunktion scheint in keiner Weise zu funktionieren.
Im letzten Beispiel habe ich erwartet, dass die Konfigurationen aktualisiert werden, wenn der Sentinel auf einen neuen Wert gesetzt wurde, oder zumindest einen Wert 30 Sekunden nach seiner Änderung aktualisieren. Keine Wartezeit aktualisiert die Werte und nur ein vollständiges Herunterfahren und Neustarten der App lädt die neue Konfiguration.
Update: Hinzufügen von app.UseAzureAppConfiguration (); In der Konfigurationsmethode beim Start und durch Festlegen eines expliziten Zeitlimits für die Konfiguration im Cache wurde die Aktualisierungsmethode so festgelegt, dass sie nach einer festgelegten Zeit aktualisiert wird. Die Sentinel-Funktionalität funktioniert jedoch immer noch nicht, und das UpdateAll-Flag für die Aktualisierungsmethode funktioniert nicht.
quelle
ConfigureServices
Methode in startuop.cs eine Konfigurationsbindung erwartet , wieservices.Configure<LogSettings>(configuration.GetSection("LogSettings"));
Antworten:
Ok, nach vielen Tests und Versuchen und Irrtümern funktioniert es.
Mein Problem war ein fehlender Dienst für Azure bei der Konfigurationsmethode. Es gibt hier ein interessantes Verhalten, da die Einstellungen weiterhin heruntergezogen werden und nur nicht aktualisiert werden, wenn dies fehlt. Sobald dies eingegeben wurde und ein ordnungsgemäßer Sentinel gemäß Dokumentation konfiguriert ist, funktioniert es mit dem updateAll-Flag. Dies ist jedoch derzeit nicht dokumentiert.
Hier ist die Lösung:
In Program.cs:
Dann in Startup.cs:
Das Einstellungsmodell, an das ich meine von Azure abgerufenen Daten binde:
Ein generischer Home-Controller, dessen Konfiguration auf ViewBag festgelegt ist, um an unsere Ansicht übergeben zu werden:
Unsere Ansicht:
Hoffe das hilft jemand anderem!
quelle