Action Filter

El objetivo de este Post es explicar los Filtros de acción (Action Filter). Un filtro de acción es un atributo que puede asociarse a una acción de un controlador o a un controlador completo, lo cual hace que se modifique la forma en que se ejecuta la acción.

El marco de ASP.NET MVC admite cuatro tipos diferentes de filtros o también conocidos como interfaces:

  1. IAuthorizationFilter
  2. IActionFilter
  3. IResultFilter
  4. IExceptionFilter

Estos filtros se ejecutan en el orden mencionado anteriormente, donde IActionFilter e IResultFilter heredan de la clase base es ActionFilterAttribute. Esta clase permite la creación de filtros de acción personalizados.  

La terminología aquí no es completamente consistente. Técnicamente, una clase que hereda de la clase ActionFilterAttribute es tanto un filtro de acción como un filtro de resultado. Sin embargo, en el sentido amplio, el filtro de acción de palabra se usa para referirse a cualquier tipo de filtro en el marco ASP.NET MVC.

Los cuatro métodos principales disponibles para sobrescribir una acción son los siguientes, en orden de ejecución:

  • Invocado antes de que se llame a la acción. Le da la oportunidad de ver la información dentro de HttpContext y tomar decisiones sobre si el proceso debe continuar procesándose.
  • Le permite ver los resultados de una acción, es decir que se ejecuta después de la acción, y determinar si algo debe suceder en ese momento.
  • Se llama antes de que se procese el resultado de la acción del controlador(Método).
  • Se invoca después de que se procese el resultado de la acción(Método), pero antes de que la salida se cargue en la secuencia de respuesta.

Antes de comenzar con el tutorial cabe destacar que un ActionFilter se puede hacer a distintos niveles.

    • En caso de que se quiera aplicar a un solo ActionResult, tan solo se tiene que indicar entre corchetes el filtro (Sin la palabra Atribute).

1

    • Otra opción es hacerlo a nivel de clase, es decir que quieras que se aplique a todos los ActionResult de un mismo Controlador.

2

    • Por último, tenemos la opción de controlar todos los ActionFilter de la aplicación, en cuyo caso se deberá añadir a la colección, predeterminada para los filtros, filters nuestro ActionFilter personalizado, esto lo podemos encontrar dentro de la carpeta App_Start y dentro de la clase FilterConfig.

3

Dentro de esta clase añadimos se añade el ActionFilter.
4

Esto no seria posible si no tuviésemos el Global.asax que es el encargado de registrar todos los filtros.

5

Una vez finalizado con los conocimientos principales pasamos a la creación de un proyecto para explicar el funcionamiento de los cuatro métodos principales de la clase base ActionFilterAttribute.

El objetivo de este proyecto es evitar que los usuarios accedan a una parte determinada de nuestra aplicación (Vista Tienda) sin antes haberse validado, esto se conseguirá con los atributos personalizados. Una vez que usuario se ha validado guardaremos cierta información en una base de datos (BBDD).

Antes de empezar, en la siguiente imagen aparecerá todos los elementos que vamos a utilizar dentro de nuestro proyecto:
6

Proyecto

En primer lugar, se crea un proyecto de tipo Web ASP.NET (.NET Framework) y se elige MVC para poder trabajar con la arquitectura que proporciona ASP.NET MVC.

Antes de seguir con este proyecto, desde SQL Server nos creamos una base de datos que en mi caso he llamado PRUEBA, y en ella se crea una tabla Usuario donde se almacenaran los usuarios que se logeen correctamente.
7

Una vez creada, insertamos un usuario que se utilizara posteriormente.
8

Lo que está en amarillo es debido ha cambios que se harán después.

Para poder utilizar esta tabla, en el proyecto dentro de la carpeta Models añadiremos un ContextoPrueba con la tabla Usuario.

Esta aplicación va a constar de dos vistas para poder ver las distintas funcionalidades de los métodos de ActionFilter, estas vistas van a ser Login y Tienda.

Dentro de la vista Login nos creamos un simple formulario para comprobar usuario y password.
9

En la vista Tienda se usará un ViewBag.Mensaje para recibir que usuario se ha logeado y poder utilizarlo para la base de datos.
21

Ahora que las vistas están creadas se debe crear el controlador, pero como en este caso se está utilizando el de Home, solo sería necesario crearse los ActionResult. En este caso, el Login consta de dos ActionResult uno para el Get y otro para el Post. En el Get simplemente devolvemos la vista y en el Post recibimos el usuario y la password del formulario de la vista.
10

En este caso simplemente estamos comprobando el usuario y la password con una cadena de String y almacenando el usuario en una sesión. En caso de que se usasen usuarios reales registrados en una base de datos, simplemente se haría la consulta y comprobar si el usuario existe y usar atributos de autorización para mayor seguridad.

La vista de Tienda recibiremos un ViewBag para podérselo mandar a la parte visual (donde poníamos Bienvenido) y será donde apliquemos nuestro filtro.
11

Después de haber creado las vistas con sus estructuras, se creará la lógica de nuestro ActionFilter. Creamos a nivel de proyecto una carpeta que se llamara Filters. Sobre dicha carpeta, se añade una clase que se llamará FiltroAttribute. La palabra Attribute es obligatoria ponerla a continuación del nombre que le hemos dado a la clase.

Una vez creada hacemos que la clase herede de nuestra clase base ActionFilterAttribute.
12

Si no heredamos de la clase base no podremos sobrescribir los métodos.
13

En esta aplicación el “usuario” no podrá ir a la tienda sin antes haberse logeado, en caso de que pinche sobre el ActionLink que lleva a la tienda le redireccionaremos al Login y esto lo haremos con el método OnActionExecuting, ya que este se ejecuta antes de la ejecución de la acción.

En este método se comprobará si la sesión es distinta de null, en caso de que sea igual a null redireccionamos al usuario al Login y si es distinto de null es que el usuario se ha logeado y le damos paso a la tienda guardándonos el nombre del usuario y mandándolo a la vista por ViewBag.
14

Después de que se ejecute el método OnActionExecuting se ejecutara el siguiente método que es OnActionExecuted. Este permite ver los resultados de la acción ya que se ejecuta después de la acción. Antes habíamos mandado el usuario logeado para comprobar que este método se ejecuta después de la acción.

Para comprobarlo, recuperaremos el usuario de la vista de Tienda (no de la sesión) y lo almacenaremos en la base de datos con un id, nombre de usuario, fecha en la que accedió, el controlador y action que visitó y las veces que lo ha visitado.
15

En la imagen anterior se puede ver que hay dos palabras clave, contexto y modelo, esto es porque en el contexto tenemos la tabla Usuario y en modelo los métodos utilizados para hacer consultas de la tabla. Los añadimos en el constructor de nuestro filtro.
16

Dentro de la clase modelo hay tres métodos, uno para buscar si existe un usuario en la tabla, otro para buscar por id y el ultimo para modificar los datos de un usuario que se está volviendo a logear y registrar fecha, zona visitada de la aplicación (en nuestro caso solo Tienda) y las veces que lleva.
17

Al ejecutar la aplicación podremos comprobar en el SQL Server que los usuarios que hemos permitido en nuestro Login están registrados en la base de datos y las veces que han entrado en la vista de la Tienda.
18

Por último, nos quedarían los métodos de OnResultExecuting y OnResultExecuted, los cuales se ejecutan antes o después de un método. Para comprobar el orden de ejecución escribiremos en la línea de salida un mensaje con el método ejecutado.

Para ello hay que crear un método privado al cual llamaremos desde los distintos métodos y le pasaremos el nombre del método y el RouteData para poder saber el controlador y el action en el que se encuentra.
19

Una vez ejecutado y hecho el proceso de Login veremos el siguiente resultado:
20

Esta parte final es una extensión para ver el orden de ejecución, ya que, el post está orientado a los métodos OnActionExecuting y OnActionExecuted.

GitHub: https://github.com/Mohamed94/ActionFilter

Autor: Mohamed Oulghazi
Curso: Microsoft MCSA Web Applications + Microsoft MCSD App Builder + Xamarin
Centro: Tajamar
Año académico: 2017-2018
Linkedin: https://www.linkedin.com/in/mohamed-oulghazi/