O que são filtros
Filtros são recursos que existem no ASP.NET MVC que nos permitem injetar comportamentos a nível de Controller, Action e em nível Global.
E nesse post vou mostrar e abordar de forma prática como trabalhar com filtros.
Inicialmente vamos trabalhar com o filtro HandlerError, que é o filtro para tratamento de exceção padrão no framework.
O registro dos filtros são feitos no Global.asax.cs :
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
namespace FiltrosNoASP.NETMVC
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application\_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
}
No método estático RegisterGlobalFilters da classe FilterConfig.cs, é onde adicionamos nossos filtros globais, ou seja, os filtros que são aplicados aqui são replicados para todos os controllers e actions de nosso projeto.
using System.Web.Mvc;
namespace FiltrosNoASP.NETMVC
{
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
}
}
No caso acima está sendo aplicado o filtro HandlerErrorAttribute que é o filtro para tratamentos de erros a nível de todo o projeto.
E como funciona o tratamento do HandlerErrorAttribute? O HandlerErrorAttribute é habilitado através da tag customErrors dentro da tag system.web no Web.config:
<customErrors mode="On">
</customErrors>
Quando habilitamos o mode On, automaticamente erros do tipo 500 são roteados para Views/Shared/Error.cshtml.
É possível mudar para uma view de erro diferente, bastar estanciar o HandlerErrorAttribute apontando para uma view customizada, é preciso que essa view esteja dentro de Views/Shared/ViewCustomizada.cshtml.
filters.Add(new HandleErrorAttribute() { View = "ViewCustomizada"})
Veja o exemplo onde simulo uma exceção na action Index do Controller Home:
public class HomeController : Controller
{
public ActionResult Index()
{
throw new Exception("Erro na Index");
return View();
}
}
Retorno:
Se a tag estivesse desabilitada o retorno seria esse:
Ok, e se eu comentar o filtro global HandlerErrorAttribute, o que acontece? Acontece um erro em tempo de execução, pois ele não consegue rotear a informação, veja:
Para saber detalhes do erro, podemos editar as informações na View de erro, nesse caso vamos alterar a view de erro a Erro.cshtml, exemplo:
@model System.Web.Mvc.HandleErrorInfo
@{
ViewBag.Title = "Error";
}
<h2>Controller: @Model.ControllerName</h2>
<h2> Action: @Model.ActionName</h2>
<h1 class="text-danger">Mensagem: @Model.Exception.Message</h1>
<h2 class="text-danger">Pilha do Erro: @Model.Exception.StackTrace</h2>
Retorno:
Filtros em nível de Controller e Action:
Para trabalhar com HandlerError a nível de controller, precisamos decorar o nosso controller, exemplo:
namespace FiltrosNoASP.NETMVC.Controllers
{
\[HandleError(View = "ViewErroController")\] //Redireciona para View ViewErroController
public class HomeController : Controller
{
public ActionResult Index()
{
throw new Exception("Erro na Index");
return View();
}
}
}
Agora vamos aplicar em nível de Action:
namespace FiltrosNoASP.NETMVC.Controllers
{
\[HandleError(View= "ViewErroController")\]
public class TesteController : Controller
{
\[HandleError(View = "ViewErroAction")\]
public ActionResult Index()
{
throw new Exception("Erro ao executar operação");
return View();
}
}
}
Hierarquicamente o tratamento de exceção utilizando filtros vem do mais genérico para mais especializado, no exemplo acima o erro acontece na Action Index, a pagina de erro customizada a ser exibida será a ViewErroAction, caso contrario a ViewErroController seria exibida, depois disso seria a nível global.
Também é possível customizar o tipo de exceção, exemplo InvalidOperationException:
namespace FiltrosNoASP.NETMVC.Controllers
{
\[HandleError(View = "ViewErroController")\]
public class TesteErroPorTipoDeExcecaoController : Controller
{
\[HandleError(View = "ViewErroActionPorTipo",ExceptionType = typeof(InvalidOperationException))\]
public ActionResult Index()
{
throw new InvalidOperationException("Erro operação Invalida");
return View();
}
}
}
Para fazer o download dos fontes clique aqui
Bom pessoal, é isso, nesse primeiro post deu para ter uma ideia de como funcionam os filtros de exceção com o HandleError.