ASP.NET MVC Preview 4 (Parte 1)

El equipo de ASP.NET MVC está en la fase final de terminar la nueva Preview 4 que esperan publicar al final de esta semana. La Preview 3 se centró en finalizar un montón de trabajo en el núcleo de las apis y en puntos de extensibilidad en ASP.NET MVC. A partir de esta Preview 4 de esta semana empezarán a aparecer nuevas características de más alto nivel que se construirán encima del núcleo y añadirán una mayor productividad.

Hay un montón de nuevas características y capacidades en esta nueva build – tantas que en realidad necesito dos post para cubrirlas todas. En este primer post veremos el nuevo sistema de Caching, Gestión de Errores y Seguridad, así como algunas mejoras para realizar test. El próximo post versará sobre las nuevas características AJAX que se han añadido con esta release.

Entendiendo los interceptores de filtros

Los atributos de los filtros de acción aportan una gran extensibilidad a APS.NET MVC que se añadió en la Preview 2. Nos permiten inyectar interceptores de código en las peticiones de un controlador MVC que se va a ejectuar antes y despues de un controlador o de sus métodos de acción. Esto permite unos escenarios de encapsulación muy interesantes en los que podemos empaquetar y reusar funcionalidad de una manera clara y declarativa.

Aquí tenéis un ejemplo de un filtro super simple “ScottguLog” que podemos usar para logear detalles sobre excepciones que se lanzan durante la ejecución de una petición. Implementar una clase de filtros personalizada es realmente sencillo – sólo tenemos que crear una clase hija de “ActionFilterAttribute” y sobreescribir los métodos apropiados para que se ejecuten antes o despues de un método de acción de un controlador, y/o antes o después de que se procese un ActionResult como respuesta:

 

Usar un filtro en una clase controladora es fácil – sólo declaramos que tiene un atributo en un método de acción, o en la propia clase (en este caso se aplicará a todos los métodos de acción del controlador):

Como podéis ver en el ejemplo, esamos aplicando dos filtros. He indicado que quiero aplicar “ScottGuLog” al método de acción “About” y quiero que el filtro “HandleError” se aplice en todos los métodos de acción del HomeController.

Anteriores Previews de ASP.NET MVC permitieron esta extensibilidad, pero no se añadieron filtros pre-compilados. ASP.NET Preview 4 incluye varios filtros para administrar el caching, errores y escenarios de seguridad.

Filtro OutputCache

El filtro [OutputCache] nos permite integrar ASP.NET MVC con las características de cacheado de ASP.NET de una forma sencilla (con ASP.NET MVC Preview 3 teníamos que escribir mucho código para conseguir esto).

Para provarlo, modificaremos el valor “Message” del método de acción “Index” del HomeController (creado por el template de proyecto de Visual Studio) para que muestre la hora actual:

Cuando ejecutamos la aplicación veremos las actualizaciones de la fecha cada vez que refrescamos la pñagina:

Podemos habilitar el cacheo de la salida para esta url añadiendo el atributo [OutputCache] en nuestro método de acción. Lo configuraremos para que cachee las respuestas durante 10 segundos de la siguiente forma:

Ahora cuando refresquemos la página veremos que la hora sólo se actualiza cada 10 seguntos. Esto es debido a que sólo se está llamando al método de acción una vez cada 10 seguntos – todas las peticiones entre esos intervalos se sirven desde la cache de ASP.NET (es decir, no se ejecuta ningún código – lo que l ohace super rápido).

Además de poder configurarse por tiempo, el atributo OutputCache también soporta la forma standar de la cache de ASP.NET (por parametros, por cabeceras, por codificación de contenido, y por lógica personalizada). Por ejemplo, en el siguiente código guardaremos diferentes versiones de la página dependiendo de un valor opcional “PageIndex” que se pasa como parámetro, y actualiza automáticamente la versión correcta dependiendo de la url desde la que se viene:

También podemos integrarlo con la base de datos de invalidaciones de ASP.NET – lo que nos permite invalidar la cache cuando las dependencias de una url son modificadas (truco: la mejor forma de hacer esto es poner una sección CacheProfile en el web.config y apuntar a él en el atributo OutputCache).

Filtro HandleError

Este filtro nos permite indicar de forma declarativa en un Controlador o en un método de acción una respuesta amigable ante posibles errores en las peticiones ASP.NET MVC.

Para provarlo, añadiremos un nuevo “TestController” a un proyecto e implementaremos un método de acción que lanzará una excepción:

Por defecto, cuando escribimos la url en el navegador, mostrará la página de error por defecto de ASP.NET a usuarios remotos (a menos que hayamos configurado la sección <customErrors> en el web.config):

Podemos cambiar el HTML del error para que sea más amigable añadiendo el atributo [HandleError]:

Este filtro capturará todas las excepciones (incluso los errores que se lanzen cuando se procesen las vistas) y mostrará una vista de error personalizada. Por defecto se intenta resolver una vista del proyecto llamada “Error” para generar la respuesta. Podemos poner esta vista en el mismo directorio que las demás vistas (por ejemplo: ViewsTest para el controlador TestController anterior), o en el directorio ViewsShared (Primero buscará en el directorio de vistas del controlador y luego se buscará en este último “directorio compartido”).

Visual Studio añade una vista de “error” por defecto dentro de ViewsShared cuando creamos un nuevo proyecto con esta Preview 4:

Cuando añadimos el atributo [HandleError] a nuestro TestController, este será el error que se mostrará por defecto a usuarios remotos (fijáos que usa la master page del proyecto de manera que está integrada en el sitio). Obviamente podemos personalizarlo, aquí tenéis cómo queda:

Para ayudar a los desarrolladores, la vista de error por defecto de Visual Studio muestra más información si se está navegando en la aplicación localmente:

Podemos desactivar esto simplemente borrando el código de la vista de Error, o poniendo la sección <customErrors> a “off” en el web.config.

Por defecto, el filtro [HandleError] capturará todas las excepciones que salten durante cada petición. Podemos especificar tipos de excepción en los que estamos interesados en capturar, y especificar errores personalizados para cada una de ellas configurando los atributos del [HandleError]:

En el código anterior mostraremos el error personalizado para las excepciones SQLException y NullReferenceException. Todas las demás mostrarán la vista de error por defecto.

Filtro Authorize

Este filtro nos permite controlar declarativamente la seguridad de acceso en un método de acción o en un controlador. Nos permite indicar que un usuario debe logearse prmiero, y opcionalmente obligar a que el usuario pertenezca a un rol concreto para poder tener acceso. El filtro funciona con todos los tipos de autenticación (incluidos Windows y basados en formularios), y permite redirigir a usuarios anónimos a un formulario de login.

Para probarlo, añadamos el filtro [Authorize] al método de acción “About” del controlador HomeController que visual studio crea por defecto:

De esta manera indicamos que un usuario debe estar logado en el sistema para poder hacer la petición de “About”. Cuando no esté logado y se intente acceder a esa url, se le negará el acceso. Si la aplicación web está configurada para usar autenticación de Windows, ASP.NET autenticará al usuario usando la identidad de Winows, y si es correcto se le permitirá el acceso. Si la aplicación web usa autenticación por formularios, el atributo [Authorize] redigirá al usuario a una página de login para que se autentique (después tendrá acceso):

Este atributo nos permte opcionalmente permitir el acceso a usuarios y/o roles. Por ejemplo, si quiero limitar el acceso sólo a mi y a Bill Gates podría escribir:

Normalmente en nuestras aplicaciones no queremos gravar a fuego los nombres de usuario en nuestro código. En lugar de eso queremos usar un concepto más alto como los “roles” para definir permisos, y mapear a los usuarios en esos roles (por ejemplo: usar active directory o una base de datos para guardar esos mapeos). El atributo [Authorize] hace sencillo el contorl de acceso con la propiedad “Roles”:

Este atributo No depende de la identidad de un usuario ni del sistema de control de roles. Trabaja sobre el objeto de ASP.NET “User” – que es extensible y nos permite usar cualquier sistema de identidad.

Clase AccountController

He mencionado ántes que el atributo [Authorize] se puede usar con cualquier sistema de autenticación. POdéis escribir o usar cualquier UI de login y/o sistema de nombreUsuario/contraseña que queramos.

Para facilitarlo, el template de proyecto de ASP.NET MVC de Visual Studio incluye un “AccountController” con vistas asociadas que implementan la autenticación por formularios con soporte para loggin in, loggin out, crear nuevos usuarios, y cambiar contraseñas. Todas las vistas se pueden personalizar independientemente de la clase AccountController:

El template Site.master también incluye una parte en la parte de arriba/derecha con la funcionalidad necesaria. Cuando usemos autenticación basada en roles nos preguntará por el login si no estamos autenticados:

y muestra un mensaje de bienvenida con un enlace para hacer logout cuando estemos autenticados en el sitio:

Si hacemos clic en el enlace de Login nos llevará a una página de Login para autenticarnos:

Los usuarios nuevos pueden hacer clic en el link de registro:

La gestión de errores también está incluida:

La clase AccountController que se añade a los nuevos proyectos usan el sistema de Membership de ASP.NET para guardar y gestionar las credenciales de usuario (el sistema de Membership usa un proveedor permitiendo que cualquier sistema de back-end para guardar los datos sea plugeable, y ASP.NET  incluye algunos providers de este tipo como Active Directory y SQL server). Si no queremos usar ninguno de elos podemos mantener la clase AccountController, las vistas y la lógica de autenticación por formularios, y sólo cambiar la lógica de cuentas de usuario. Para la próxima preview de ASP.NET MVC estamos planeando encapsular la lógica de interacción entre el AccountController y el sistema de identidad de usuarios tras una interfaz – lo que hará más sencillo enlazar nuestro propio sistema de almacenamiento (sin tener que implementar un provider de membership completo) así como facilitar los test unitarios en ambos.

Esperamos que esto aporte una forma sencilla de empezar, y que nos permita tener rápidamente un sistema de seguridad end to end tan pronto como creamos un nuevo proyecto.

Testeando TempData

Una última mejora que saborear en este primer post es sobre algunas mejoras que se han hecho en las clases Controladoras que nos permite crear testear más fácilmente la colección TempData. La propiedad TempData nos permite guardar datos que queremos guardar para peticiones futuras de un usuario. Tiene la semántica de una petición (después de la cual se eliminará). Se usa muy habitualmente en escenarios MVC en el que queremos  realizar una redirección del lado del cliente para cambiar la url en el navegador, y queremos una forma simple de guardar esos datos.

En versiones anteriores teníamos que usar objetos Mock para testear la colección TempData. Con la Preview 4 no necesitaremos estos objetos nunca más. Podemos añadir y verificar objetos en la colección TempData de los controladores directamente en los test unitarios (por ejemplo: rellenar la propiedad TempData de un controlador ántes de llamar a su método de acción, o comprobar que la acción ha actualizado la TempData después de devolver). La semántica actual de guardado de esta colección está encapsulada en una propiedad a parte llamada TempDataProvider.

Conclusión

Este post ofrece un primer vistazo a un número de nuevas características y cambios que vienen en ASP.NET MVC Preview 4. En el próximo post veremos las nuevas funcionalidades AJAX que se han añadido, y mostraremos cómo aprovecharlas.

Espero que sirva.

Scott.

Traducido por: Juan María Laó Ramos.

toH tlhIngan Hol DajatlhlaH ‘e’ DaneH’a’?

Artículo original.

0 comentarios sobre “ASP.NET MVC Preview 4 (Parte 1)”

  1. Hola, excelente explicación de Filtros. Una pregunta, ya tengo armada mi primer aplicación en MVC4 y me esta costando un poco usar por un lado HandleError y combinarlo con Authorize.

    No se si debo usar HandleError a nivel de clase y luego en cada controlador con su Authorize, entonces siempre va a capturar errores y cuando un usuario no tenga autorizacion a un controlador, tambien lo va a capturar HandleError.

    O esoy confundido y uso se usa para una cosa y otro para otra.

    Lo que yo quiero hacer, que tanto si se produce un error, por ejemplo dentro de un controlador con una operacion de division sobre cero, vaya a una pagina de error por default.

    Pero cuando un usuario no esta dentro del grupo del AD, el Authorize lo capture y vaya a la misma pagina.

    tengo dudas con esto !!!

    Saludos
    Eduardo

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *