Para entrar en materia, en dicho post presentamos
StaticFilesMiddleware
, el componente proporcionado por ASP.NET Core que, insertado convenientemente en el pipeline, es capaz de capturar las peticiones cuya ruta coincide con un recurso estático presente en el sistema de archivos y retornar su contenido al cliente.Sin embargo, el paquete Nuget Microsoft.AspNetCore.StaticFiles contiene otros middlewares que cubren necesidades que podemos encontrar con frecuencia cuando en nuestras aplicaciones necesitemos gestionar contenidos estáticos.
Y aún a riesgo de resultar cansino, antes de continuar os recuerdo que seguimos trabajando con versiones preliminares de ASP.NET Core, por lo que todavía podrían introducirse cambios en el producto.
Publicado por José M. Aguilar a las 9:10 a. m.
Etiquetas: aspnetcore, aspnetcoremvc, middlewares, static files
Una de las principales características del nuevo ASP.NET Core es su diseño modular. El framework no es ahora un mastodonte monolítico sino un gran conjunto de pequeños componentes que incluiremos en nuestras aplicaciones exclusivamente cuando sea necesario.
Esto, que a priori se muestra como una ventaja en términos de rendimiento y flexibilidad de nuestros sistemas, presenta también algunos pequeños inconvenientes que debemos tener en cuenta a la hora de desarrollar aplicaciones.
Por ejemplo, en versiones anterior de ASP.NET no teníamos que preocuparnos demasiado de la gestión de los archivos estáticos (JS, CSS, HTML, fuentes...) porque teníamos por abajo a IIS que se encargaba de procesar las peticiones a este tipo de recursos. Ahora, tras la llegada de ASP.NET Core, las aplicaciones que utilicen archivos estáticos deberán incluir expresamente código para procesarlos.
Pero antes de continuar, recordaros que aún estamos jugando con una release candidate de ASP.NET Core, por lo que parte de lo que veamos a continuación podría no ser totalmente cierto en unas semanas.
Publicado por José M. Aguilar a las 9:10 a. m.
Etiquetas: aspnetcore, aspnetcoremvc, desarrollo, static files
Seguro que estamos todos de acuerdo en que el nuevo sistema de configuración proporcionado por ASP.NET Core mejora bastante lo que teníamos en las versiones más tradicionales de ASP.NET.
Y la posibilidad de almacenar settings en formatos como .INI o .XML resulta interesante, el formato JSON me parece de lo más cómodo y apropiado para muchos escenarios en los que antes no lo teníamos tan sencillo, como definir configuraciones con un cierto nivel de jerarquía como la siguiente:
Seguro recordaréis que tradicionalmente tanto MVC como Web API han sido frameworks muy guiados por convenciones, es decir, venían de serie diseñados con un conjunto de pautas o normas a las que debíamos ceñirnos si queríamos aprovechar todo su potencial.
Teníamos convenciones para las rutas, de ubicación de vistas, para nombrar los controladores, nombrado de acciones según el verbo HTTP mediante el cual se pretendía acceder a una función del API, y algunas más.
Algunas de estas convenciones se podían cambiar fácilmente usando mecanismos directos proporcionados por los propios frameworks, pero había otras que era bastante más difícil hacerlo y a veces teníamos que hacer auténticos malabarismos con las piezas internas del marco de trabajo para conseguir nuestros objetivos.
ASP.NET Core MVC simplifica bastante la adaptación del framework a nuestras necesidades, proporcionando fórmulas muy potentes para la creación de convenciones personalizadas.
<Disclaimer>En el momento de escribir estas líneas ASP.NET MVC Core 1.0 se encuentra en RC1, por lo que algunos detalles aún pueden variar en la versión final</Disclaimer>
En esta ocasión, comentaremos muy brevemente una gran ausencia en las vistas Razor: la directiva
@helper
, que no estará disponible en la primera versión de ASP.NET Core MVC.<Disclaimer>Aunque en una Release Candidate las cosas no deberían cambiar, ya han demostrado bastantes veces que sí que cambian, por lo que algo de lo que digamos aquí podría no ser cierto en la versión final del producto</Disclaimer>
Esto no es un tema reciente: hace ya bastantes meses, la implementación que había era bastante incompleta y no encajaba bien en la nueva arquitectura, por lo que tras algunos debates y reuniones de diseño, se decidió que lo mejor era eliminar esta directiva.
Y hoy vamos a comentar muy rápidamente otro cambio que han introducido hace relativamente poco tiempo, y que afecta a lo que contábamos hace algunas semanas sobre la nueva carpeta "wwwroot", el lugar donde colocaremos todos los archivos estáticos usados por nuestra aplicación web.
Este mismo criterio se aplicó a otros productos que también habían sido creados from scratch, como .NET Core, que se versionó como 5.0, o el nuevo Entity Framework, cuya flamante primera versión sería la 7.0.
La cuestión es que este enfoque en la asignación de nombres y versiones no fue del agrado de muchos, que pensábamos que algo creado desde cero y que rompía en bastantes aspectos con lo anterior no tenía sentido lanzarlo a la calle simplemente como un incremento de versión de un producto existente. Es difícil de explicar y difícil de comprender.
Pues bien, hace unas horas recibíamos el comunicado oficial de que ASP.NET 5 ha cambiado su nombre por ASP.NET Core.
Publicado por José M. Aguilar a las 11:39 a. m.
Etiquetas: aspnet5, aspnetcore, aspnetcoremvc, entity framework, noticias
Lo primero, agradecer a los numerosos asistentes que aparcaron sus quehaceres diarios para pasar la jornada con nosotros; espero que os haya resultado interesante. Muchas gracias también a los amigos de Plain Concepts por patrocinar el evento, y a mi inigualable compañero de escenario, Javier Suárez, por gestionarlo todo tan bien y, por supuesto, por sus interesantes presentaciones.
El concepto de proceso de peticiones basado en el pipeline no es algo nuevo, pero ciertamente es en ASP.NET Core donde se hace más explícito y visible a los desarrolladores.
Y aunque anteriormente también hemos trabajado con middlewares (en ASP.NET 4.x los módulos y handlers podían ejercer funciones similares, y más recientemente, en OWIN ya existía el mismo concepto), es ahora cuando debemos conocerlos bien si queremos llegar a comprender y dominar la nueva plataforma ASP.NET Core.
Este este post vamos a profundizar un poco en el proceso de peticiones en ASP.NET Core, y veremos lo sencillo que resulta crear middlewares personalizados que participen en dicho proceso.
Tomando el relevo, "Reconnect(); // 2015" es un evento organizado por el grupo de usuarios .NET de Sevilla (Cartuja.NET) en el que veremos los aspectos más destacables de esas novedades.
Será el próximo jueves 10 de diciembre, una mañana completa cuya agenda es la siguiente:
9:15 - 9:30 Registro.
9:30 - 10:30 Keynote. Javier Suárez, Josué Yeray y Marcos Cobeña.
10:30 - 11:30 ASP.NET 5 & MVC 6 (RC 1). Jose María Aguilar.
11:30 - 12:00 Descanso & Networking.
12:00 - 13:00 Universal Windows Platform. Javier Suárez y Josué Yeray.
13:00 - 14:00 Desarrollo móvil con Xamarin. Javier Suárez, Josué Yeray y Marcos Cobeña.
14:00 - 14:15 Cierre.
El lugar: WorkINCompany - Calle Rioja, 13, 41001 Sevilla.
Podéis registraros siguiendo este enlace; no tardéis, que las plazas son limitadas :)
¡Nos vemos por allí!
Publicado en Variable not found.
Publicado por José M. Aguilar a las 9:40 a. m.
Etiquetas: aspnet5, aspnetcore, aspnetcoremvc, cartujadotnet, charlas, eventos
Hasta ahora hemos visto cómo gestionar las excepciones producidas desde nuestras aplicaciones utilizando el middleware
ExceptionHandlerMiddleware
, y cómo obtener información sobre dichas excepciones desde su código manejador. Esto nos permitía un buen grado de control sobre los errores HTTP 500, pero el amigo Juan, muy atento a lo que íbamos viendo, preguntaba:"Siguiendo con la captura de excepciones, esta vez en mvc6 como se podría capturar los códigos de estado como por ejemplo 404"Obviamente el resto de errores HTTP entre el 400 (errores en cliente) y el 599 (errores en servidor) no son capturados por
ExceptionHandlerMiddleware
porque en realidad no se deben a excepciones generadas desde nuestra aplicación sino a otros problemas que han podido surgir durante el proceso de la petición. Por ello, requieren un tratamiento distinto que de nuevo viene en forma de middleware.Hace unos días comentábamos la desaparición de la sección <customErrors> en ASP.NET Core, y la forma de implementar páginas de error personalizadas en esta nueva versión del framework.
Sin embargo, hay una cosa que dejé en el tintero y que el amigo Max resaltó en los comentarios del post:
"[…] Cuando se hace la petición interna a la acción HomeController.Error ¿como puedo saber exactamente el error que se ha producido si quiero mostrar un mensaje de error concreto para cada caso? Por ejemplo imagínate que quiero mostrar vistas diferentes para cada tipo de excepción o que aparezca sólo el texto de la excepción pero sin mostrar más datos"En otras palabras, cuando el middleware
ExceptionHandlerMiddleware
pasa el control a la acción que procesará el error, ¿cómo podemos obtener información sobre la excepción que se produjo, por ejemplo para poder mostrar vistas o mensajes de error un poco más específicos?Qué pregunta tan interesante, ¿verdad?
Hoy vamos a ver en profundidad uno de estos helpers, AnchorTagHelper, cuya misión es facilitarnos la creación de enlaces a controladores/acciones de nuestra aplicación. Para hacer más sencilla su comprensión, lo haremos mediante casos prácticos, y comparando cada ejemplo con la fórmulas que hemos usado tradicionalmente y que seguro conocéis, los helpers HTML.
<warning>ASP.NET aún se encuentra en desarrollo, por lo que detalles de lo que contemos por aquí aún podrían variar en la versión final</warning>
Hace bastantes meses, allá por febrero, publiqué el post “Inyección de dependencias en ASP.NET 5”, donde describía el sistema integrado de inyección de dependencias que se estaba construyendo en el que todavía se denominaba ASP.NET 5.
Sin embargo, las cosas han cambiado un poco desde entonces, por lo que he pensado que sería buena idea reeditar el artículo y actualizarlo al momento actual, con la beta 8 de ASP.NET Core a punto de publicarse.
<disclaimer>Aunque el producto está cada vez más estable y completo, aún podrían cambiar cosas antes de la versión definitiva, incluso antes de tener la release candidate en la calle.</disclaimer>
Si no sabes aún lo que es inyección de dependencias, el resto del post te sonará a arameo antiguo. Quizás podrías echar previamente un vistazo a este otro, Desacoplando controladores ASP.NET MVC, paso a paso, que aunque tiene ya algún tiempo, creo que todavía es válido para que podáis ver las ventajas que nos ofrece esta forma de diseñar componentes.
Para los perezosos, podríamos resumir el resto del post con una frase: ASP.NET Core viene construido con inyección de dependencias desde su base, e incluye todas las herramientas necesarias para que los desarrolladores podamos usarla en nuestras aplicaciones de forma directa, en muchos casos sin necesidad de componentes de terceros (principalmente motores de IoC que usábamos hasta ahora). Simplemente, lo que veremos a continuación es cómo utilizar esta característica ;)
Html.ActionLink()
o Html.TextBoxFor()
nos han permitido durante años crear interfaces de forma sencilla y productiva, pues se trataba de métodos muy reutilizables capaces de ejecutar lógica de presentación y generar bloques de HTML por nosotros (o CSS, o incluso Javascript).De hecho, los helpers han sido la fórmula recomendada para crear componentes reutilizables de generación de código de marcas en las páginas de nuestras aplicaciones MVC y son muy utilizados tanto por el propio framework como por componentes visuales de terceros. Pero esto no implica que fuera una solución perfecta o exenta de problemas…
En ASP.NET Core MVC 1.0 se le ha unido un compañero llamado _ViewImports.cshtml, cuya finalidad y funcionamiento es parecido al tradicional ViewStart, porque se procesa antes de ejecutar una vista e igualmente afecta a todas las vistas que se encuentren por debajo de este archivo en el árbol de directorios, aunque aporta algunas diferencias bastante interesantes. Comentamos a continuación los aspectos más destacables.
Publicado por José M. Aguilar a las 9:10 a. m.
Etiquetas: aspnetcore, aspnetcoremvc, desarrollo, novedades
Aunque algunos miembros del equipo habían ido adelantando pistas bastante clarificadoras, e incluso el amigo José Manuel Alarcón ya había publicado al respecto, hasta ahora no podíamos decir que tuviéramos información pública, casi totalmente precisa y de primera mano. Pero por fin ha llegado, y como era de esperar, a través del repositorio oficial del proyecto en Github.
Resumidamente, así está la planificación a día de hoy para ASP.NET Core y MVC:
- La Beta 6 estaba prevista para ayer, 27 de julio de 2015, aunque por temas de última hora este lanzamiento se ha pospuesto un día; de hecho, es posible que en el momento en que estéis leyendo esto haya sido ya publicada o estén a punto de hacerlo. Sus principales novedades serán el soporte para localización, la posibilidad de targeting para .NET 4.6, buffering y caching de resultados, caché distribuido a través de SQL Server, y algunas otras características.
- La Beta 7, prevista para el 24 de agosto, estará centrada en el desarrollo multiplataforma sobre .NET Core. Se lanzarán los entornos de ejecución para Mac y Linux, facilitando los workflows básicos del desarrollador y la descarga e instalación de los componentes.
- La Beta 8 se lanzará el 21 de septiembre y será la última en la que se añadan features. Se centrará también en la integración con VS y VS Code.
- A partir de este momento, el producto entrará en una fase de estabilización y mejora de fiabilidad y rendimiento. La primera versión candidata, ASP.NET Core RC 1 se lanzará en noviembre de 2015, siendo la primera distribución production-ready y cross-platform completa. Dependiendo del feedback, ya se verá si se lanzan RC posteriores hasta llegar a la RTM.
- La versión RTM de ASP.NET Core/MVC no verá la luz hasta el primer trimestre de 2016. Esto quiere decir que, si la cosa no se retrasa, podríamos tener estas tecnologías disponibles a finales de marzo.
- Tras ello, se espera la llegada de otros temas que no podrán ser incluidos en la RTM, como el soporte para Visual Basic, SignalR o Web Pages. En el roadmap estiman que estos temas se retrasarán hasta el Q3, es decir, que no habrá novedades al respecto hasta verano de 2016.
Publicado en Variable not found.
HttpContext.Current.IsDebuggingEnabled
para determinar si una aplicación web está ejecutándose en modo depuración o no, lo cual podía ser útil a la hora de introducir porciones de código específicas para cada caso. El valor de esa propiedad estaba directamente relacionado con el de la propiedad
debug
del tag <compilation>
presente en el archivo de configuración web.config.Como sabemos, en ASP.NET Core esto no sería posible por tres motivos:
- Primero, por la archiconocida desaparición del web.config.
- Segundo, porque al eliminar la dependencia con System.Web, ya no existen ni
HttpContext.Current
ni la propia clase estáticaHttpContext
. - Y tercero, porque no existe un modo “debug” como tal, sino distintos entornos de ejecución (development, staging, production, etc.) que pueden establecerse mediante línea de comandos o variables de entorno del sistema operativo
Por convención, los registrábamos en una clase llamada FilterConfig, habitualmente ubicada en la carpeta /App_Start del proyecto, y cuya pinta era más o menos la siguiente:
Este código era llamado durante la inicialización de la aplicación desde el evento
Application_Start()
del archivo Global.asax:El problema con la inyección de dependencias en los filtros es la instanciación de éstos, pues al definirse en forma de atributos de .NET no puede realizarse de forma controlada, o al menos lo suficientemente controlada como para poder inyectarles parámetros en el constructor o cargar sus propiedades desde un contenedor de inversión de control. Y aunque los filter providers aportaron alguna solución vía los contenedores IoC más populares, aún no eran una solución todo lo limpia que debería ser.
Pero como decía David Wheeler, “Cualquier problema en ciencias de la computación puede ser solucionado con otro nivel de indirección”… y eso mismo han debido pensar la gente del equipo de ASP.NET en Microsoft, cuando la solución que han dado consiste, básicamente, en crear un filtro capaz de instanciar otros filtros usando el contenedor de servicios integrado :)