Lo que intento hacer: intento configurar la configuración de la aplicación de Azure con una aplicación web .net core 2.1 mvc con una clave centinela en la configuración de la aplicación de Azure, con el objetivo de poder cambiar las claves en azul, y ninguna de las claves se actualizará en mis aplicaciones hasta que el valor centinela haya cambiado. En teoría, esto debería permitirme intercambiar configuraciones de forma segura.
Cuál es mi problema: cuando hago esto, no hay un método WatchAndReloadAll () disponible para ver el centinela en IWebHostBuilder, y los métodos alternativos Refresh () no parecen actualizar la configuración a medida que se establecen.
Información general y lo que he probado: asistí a VS Live - San Diego, la semana pasada y vi una demostración sobre la Configuración de la aplicación de Azure. Tuve algunos problemas al intentar que la aplicación actualizara los valores de configuración cuando lo implique, por lo que también hice referencia a esta demostración que describe cómo hacerlo también. La sección relevante está a unos 10 minutos. Sin embargo, ese método no parece estar disponible en IWebHostBuilder.
Documentación a la que me refiero: en la documentación oficial no hay referencia a este método; consulte doc quickstart .net core y doc dynamic configuration .net core
Mi entorno: uso de dot net core 2.1 que se ejecuta desde Visual Studio Enterprise 2019, con el último paquete nuget de vista previa para Microsoft.Azure.AppConfiguration.AspNetCore 2.0.0-preview-010060003-1250
Mi código: en la demostración, crearon un IWebHostBuilder a través del método CreateWebHostBuilder (string [] args) de esta manera:
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>();
}
También lo intenté de esta manera, usando la documentación actual:
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>();
Luego, en mi clase de inicio:
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?}");
});
}
y finalmente mi modelo de configuración de configuración:
public class Settings
{
public string BackgroundColor { get; set; }
public long FontSize { get; set; }
public string FontColor { get; set; }
public string Message { get; set; }
}
Ahora, en mi controlador, extraigo esos ajustes y los tiro a una bolsa de visualización para que se muestren en la vista.
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();
}
}
Una vista simple para mostrar los cambios:
<!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>
Puedo hacer que baje la configuración la primera vez, sin embargo, la funcionalidad de actualización no parece funcionar de ninguna manera.
En el último ejemplo, esperaba que las configuraciones se actualizaran cuando el centinela se estableciera en cualquier valor nuevo, o al menos, actualizar un valor 30 segundos después de que se cambiara. Sin esperas, los valores se actualizan, y solo un apagado y reinicio completo de la aplicación carga la nueva configuración.
Actualización: Agregar aplicación.UseAzureAppConfiguration (); en el método de configuración al inicio, y al establecer un tiempo de espera explícito en la memoria caché para la configuración, se arregló el método de actualización para actualizarse después de un período de tiempo fijo, pero la funcionalidad centinela aún no funciona, ni el indicador updateAll en el método de actualización.
fuente
ConfigureServices
método en startuop.cs, comoservices.Configure<LogSettings>(configuration.GetSection("LogSettings"));
Respuestas:
Ok, después de muchas pruebas y pruebas y errores, lo tengo funcionando.
Mi problema era que faltaba un servicio para azure en el método de configuración. Aquí hay un comportamiento interesante, ya que aún eliminará la configuración, simplemente no se actualizará, si esto falta. Por lo tanto, una vez que se haya instalado y con un centinela adecuado configurado por documentación, funciona con el indicador updateAll. Sin embargo, esto no está documentado actualmente.
Aquí está la solución:
En Program.cs:
Luego en Startup.cs:
El modelo de configuración a la que estoy vinculando mis datos recuperados azules:
Un controlador doméstico genérico con la configuración configurada en ViewBag para pasar a nuestra vista:
Nuestra vista:
¡Espero que esto ayude a alguien más!
fuente