lunes, 18 de abril de 2016

IHostingEnvironment en Asp.net Core, Environment y uso de variables


Cuando desarrollamos aplicaciones web necesitaremos 'hacer cosas' en función del entorno donde está desplegada la web. Por poner un ejemplo en desarrollo si se produce una excepción nos interesa que nos lleve a una página donde nos muestre el máximo de información sobre el fallo en cambio en pre o producción tal vez no queramos que se muestre todo el detalle sobre que ha provocado la excepción sino que enviamos el detalle a algún servicio o log y mostramos una página más bonita.

Por defecto cuando creas un proyecto web asp.net core en Visual Studio la template te proporciona la clase Startup:


Por otro lado si vais a las propiedades del proyecto web veréis que oob tenemos una variable de entorno definida en el profile por defecto.


Aquí podemos añadir variables (añado Test:Value) que luego podemos usar en código del siguiente modo:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
   app.Run(async (context) =>
   {
      await context.Response.WriteAsync(Environment.GetEnvironmentVariable("Test") + "\r");
   }
}
El resultado será:

Value

Pero bueno lo que quería mostrar en este post es que información nos proporciona IHostingEnvironment en asp.net core, así que vamos a ello. En este fragmento de código estoy mostrando el nombre del entorno, muestro el contenido del directorio Root y por último vemos por pantalla el valor de IsDevelopment() e IsProduction(). Sí... hay modos más elegantes de concatenar strings en C# ...
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
   app.Run(async (context) =>
   {
      await context.Response.WriteAsync("Nuestra Variable Test: " + Environment.GetEnvironmentVariable("Test") + "\r");
               
      await context.Response.WriteAsync("Environment.Name: " + env.EnvironmentName.ToString() + "\r");

      IDirectoryContents directoryContent = env.WebRootFileProvider.GetDirectoryContents("");
      await context.Response.WriteAsync("Directorio Root: \r");
      foreach (var item in directoryContent) {
         await context.Response.WriteAsync(item.Name + "\r");
      }

      await context.Response.WriteAsync("isDevelopment() = " + env.IsDevelopment().ToString() + "\r");
      await context.Response.WriteAsync("isProduction() = " + env.IsProduction().ToString() + "\r");
   });
}
Si ejecutamos en IIS Express veremos los siguientes valores por pantalla:
Nuestra Variable Test: Value
Environment.Name: Development
Directorio Root: 
web.config
isDevelopment() = True
isProduction() = False
En cambio si realizo un deploy a Azure (equivaldría a producción en esta prueba de concepto), el mismo código produce el siguiente output:
Nuestra Variable Test: 
Environment.Name: Production
Directorio Root: 
ApplicationInsights.config
App_Data
bin
hostingstart.html
web.config
isDevelopment() = False
isProduction() = True
Como veis el resultado cambia, si os fijáis en la variable de entorno que he definido al principio en producción no tiene valor. En Azure si voy al sitio web que me he creado podría añadir la variable de entorno Test como veis en la imagen y con esto al volver a cargar la página vería el valor correspondiente en el output.



Hasta aquí el post de hoy, que vaya bien la semana!