O ASP.Net MVC provê Action Filters que executam lógicas de filtragem antes ou depois que um Action Method é chamado. Action Filters são atributos personalizados que fornecem através de meios declarativos a possibilidade de adicionar um filtro que será executado para adicionar um comportamento aos métodos da Controller.
Action Filters fornecem uma técnica simples e poderosa de modificar ou melhorar o pipeline do ASP.Net MVC através da “injeção” de comportamento em determinados momentos ajudando a resolver diversas situações em algumas ou todas as partes da aplicação.
Os Action Filters são um dos tipos de filtros que o ASP.Net MVC 4 possui, estes filtros estão disponíveis para uso sem necessidade de customização, são eles:
- Authorization Filter – Segurança e controle de usuários autenticados
- Action Filter – Injeção de comportamento na execução de um ActionMethod
- Result Filter – Injeção de comportamento na execução de um ActionResult
- Exception Filter – Captura e tratamento na ocorrência de Exceptions
Um exemplo muito clássico do uso de Actions Filters é na Autorização de usuários logados:
[Authorize] public class AccountController : Controller { [AllowAnonymous] public ActionResult Login(string returnUrl) { ViewBag.ReturnUrl = returnUrl; return View(); } }
O uso dos Action Filters é feito decorando a Controller ou Action Method, no exemplo acima está sendo requerida a autorização de usuário para todos os métodos da Controller, caso isso seja necessário apenas para um método o Action Filter [Authorize] pode decorar apenas o método em questão, um exemplo disto é o próprio método de Login, pois nele é aplicado o filtro [AllowAnonymous] abrindo uma exceção para a regra geral aplicada na Controller.
O uso de Action Filters é muito comum, porém muitas vezes necessitamos de um comportamento diferenciado e nesses casos é possível criar o seu próprio Action Filter para definir um comportamento específico durante a chamada dos Actions Methods da aplicação.
Criando um Action Filter Customizado
O exemplo a ser abordado é muito simples, uma aplicação deve possuir um comportamento de exibir propagandas (conhecido como Advertising ou ADS) nas Views. Uma forma de atender este requisito é criando um Action Filter que fará este trabalho.
Roteiro
- Criar uma aplicação ASP.Net MVC 4 no Visual Studio chamada MvcFilterExample;
- Adicionar uma nova classe chamada ExibirAdsActionFilter na pasta Filters;
- Registrar o Action Filter de forma global ou utilizá-lo diretamente na Controller;
- Testar e validar o funcionamento do novo Action Filter.
A classe ExibirAdsActionFilter possui a seguinte estrutura
using System.Web.Mvc; namespace MvcFilterExample.Filters { public class ExibirAdsActionFilter : ActionFilterAttribute, IActionFilter { void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext) { filterContext.Controller.ViewBag.ConteudoAd = GerarConteudoAD(); } void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext) { AtualizarExibicaoAD(); } private string GerarConteudoAD() { return "<hr/><h2>Propaganda Aqui!<h2 /><hr/>"; } private void AtualizarExibicaoAD() { // Neste método pode ser executada uma atualização // do contador de exibições de determinada propaganda. } } }
Para construir o Action Filter proposto é necessário herdar a classe ActionFilterAttribute e implementar a interface IActionFilter.
A classe ActionFilterAttribute é a base para todos attribute filters, esta classe provê os seguintes métodos:
- OnActionExecuting (ActionExecutedContext filterContext): Chamado um pouco antes do Action Method.
- OnActionExecuted (ActionExecutingContext filterContext): Chamado após o Action Method e antes do Action Result ser executado (antes de renderizar a View).
- OnResultExecuting (ResultExecutingContext filterContext): Chamado um pouco antes do Action Result (antes de renderizar a View).
- OnResultExecuted (ResultExecutedContext filterContext): Chamado após o Action Result ser executado (após a View ter sido renderizada).
Pelo fato de estar sendo utilizada a interface IActionFilter apenas os métodos OnActionExecuting e OnActionExecuted necessitam ser implementados.
(Os últimos dois métodos atendem a filtros do tipo Result Filters e são implementados pela interface IResultFilter).
O exemplo é bem simples, o método OnActionExecuting gera o conteúdo de uma propaganda e armazena em uma ViewBag e o método OnActionExecuted contabiliza o número de visualizações.
Utilizando e Registrando Action Filters
Exitem 3 maneiras de utilizar este um novo Action Filter
- Manualmente em uma Controller (todos os Actions Methods farão uso do filtro)
- Manualmente nos Action Methods que farão uso do filtro
- Registrando globalmente o filtro na aplicação (a aplicação inteira irá usar o filtro)
Para utilizar manualmente o Action Filter basta adicionar a referência do namespace da classe do filtro e decorar a Contoller ou Action Method com [ExibirAdsActionFilter]
using System.Web.Mvc; // Referência das classes de filtro using MvcFilterExample.Filters; namespace MvcFilterExample.Controllers { // Usando o filtro para toda Controller [ExibirAdsActionFilter] public class ClienteController : Controller { // Usando o filtro para cada Action Method [ExibirAdsActionFilter] public ActionResult Index() { return View(); } } }
OBS – Uma vez que a Controller foi decorada com o uso do filtro, todos os Action Methods assumem esse comportamento, não é necessário decorá-los.
Para registrar globalmente o Action Filter é necessário modificar a classe FilterConfig dentro da pasta App_Start
using System.Web.Mvc; // Referência das classes de filtro using MvcFilterExample.Filters; namespace MvcFilterExample { public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); // Novo filtro adicionado filters.Add(new ExibirAdsActionFilter()); } } }
OBS – Ao registrar o Action Filter globalmente não é mais necessário manter a referencia MvcFilterExample.Filters e a decoração [ExibirAdsActionFilter] na Controller ou Action Methods, pois o registro aplicará o uso do filtro para toda a aplicação.
Para validar o funcionamento do filtro basta chamar o ViewBag ConteudoAd em uma View
<table> <tr> <td> @Html.Raw(@ViewBag.ConteudoAd) </td> </tr> </table>
Atente-se ao modo de utilização do filtro, se foi registrado globalmente ou se está sendo utilizada em uma Controller específica, caso a ViewBag seja chamada através de uma Controller que não utiliza o Filtro ela retornará vazia. Abaixo o resultado da chamada da ViewBag criada dinamicamente pelo Action Filter customizado para propagandas.
O Action Filter está implementado e em funcionamento.
Resumo
O uso de Action Filters customizados é muito comum e atendem a diversas necessidades rotineiras como:
- Validação de regras de acesso de usuários
- Log de atividades dos usuários
- Captura de IP ou outras informações do cliente
- Exibição de propagandas
- Tratamento e notificações de exceptions
Espero que seja útil!
Feedbacks ou dúvidas são sempre muito bem vindos e respondidos, utilize os comentários abaixo para continuarmos trocando informações.