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 <customErrors mode=”Off”> 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 funcionar filtros de exceção com o HandleError.