O processo de manipulação de erros personalizados no ASP.NET MVC (3 neste caso) parece incrivelmente negligenciado. Eu li as várias perguntas e respostas aqui, na Web, páginas de ajuda de várias ferramentas (como Elmah), mas sinto que segui um círculo completo e ainda não tenho a melhor solução. Com sua ajuda, talvez possamos definir uma nova abordagem padrão para o tratamento de erros. Eu gostaria de manter as coisas simples e não projetar demais isso.
Aqui estão meus objetivos:
Para erros / exceções do servidor:
- Exibir informações de depuração no dev
- Exibir página de erro amigável na produção
- Registre erros e envie-os por e-mail ao administrador em produção
- Código de status HTTP de retorno 500
Para erros 404 não encontrados:
- Exibir página de erro amigável
- Registre erros e envie-os por e-mail ao administrador em produção
- Código de status HTTP 404 de retorno
Existe uma maneira de atingir esses objetivos com o ASP.NET MVC?
Respostas:
Vou compartilhar a maneira como acabei fazendo isso, que fazia parte da pergunta original.
Primeiro, os problemas que encontrei:
Com customErrors ativado (ou seja, em produção), o
HandleError
atributo global engole exceções e renderiza sua exibição de erro, mas não é possível registrá-lo com uma ferramenta adicional como elmah, pois elmah nunca a vê. Você poderia registrá-lo em sua opinião, suponho, mas é uma visão que parece errada. O atributo global HandleError aparece novo no modelo de projeto do MVC 3 RTM Visual Studio.customErrors com URLs para pontos de extremidade MVC retorna 302 códigos de status. Existe a propriedade redirectmode, mas você não pode corresponder a URLs do mvc em customErrors e usar o modo ResponseRewrite. ( https://stackoverflow.com/questions/781861/customerrors-does-not-work-when-setting-redirectmode-responserewrite/3770265#3770265 )
Evitar completamente os customErrors e manipular tudo o que é personalizado no seu aplicativo leva a muita complexidade, IMO. (Adorei isso: https://stackoverflow.com/questions/619895/how-can-i-properly-handle-404s-in-asp-net-mvc/2577095#2577095 , mas não era adequado para o nosso projeto)
Minha solução
Tirei MVC da equação completamente. Eu removi
HandleErrorAttribute
o filtro global em global.asax e concentrei-me inteiramente na configuração customErrors, deslocando-o para usar os redirecionamentos de WebForm e alterar para o modo de redirecionamentoResponseRewrite
para evitar os 302 códigos de resposta HTTP.Em seguida, no
NotFound.aspx
evento page_load, definaResponse.StatusCode
como 404 e em Error.aspx, defina o código 500.Resultados:
Os objetivos de ambos foram alcançados com os logs do Elmah, a página de erro amigável e o código de status com uma linha de código no code-behind. Não estamos fazendo o "MVC Way" como a solução anterior faz, mas estou bem com isso se forem duas linhas de código.
fonte
Eu acho que o MVC, ASP e sua estrutura favorita de registro / tratamento de exceções podem lidar com seus objetivos muito bem. O ELMAH e a Enterprise Library fornecem fácil manuseio e registro de exceções, então escolha o seu favorito. Não vou falar dos prós e contras de cada um aqui.
NOTA: você não pode exibir uma página de erro amigável E retornar um HTTP 404 ou 500 como sugere sua pergunta. Quando você retorna uma página de erro amigável, o código HTTP retornado ao seu navegador será 302. Este é um redirecionamento para a página de erro amigável.
Páginas de erro amigáveis
Parece que você pode atingir seus objetivos com as boas configurações do web.config que fazem parte do ASP.net há algum tempo. Você menciona a exibição de informações de depuração no desenvolvimento e a exibição de páginas amigáveis na produção. Você pode usar a seção de erros personalizados do web.config para isso (defina CustomErrors = "Off" para mostrar informações de depuração). Vou assumir que você está familiarizado com o atributo CustomErrors, se não ler isso:
http://msdn.microsoft.com/en-us/library/h0hfz6fc.aspx
Se você precisar de maior granularidade de controle sobre quais exibições de erro são exibidas, use o Atributo HandleError do MVC. Dessa forma, você pode escolher diferentes visualizações de erro para cada Ação / Controlador.
http://weblogs.asp.net/scottgu/archive/2008/07/14/asp-net-mvc-preview-4-release-part-1.aspx
Log de exceção
Parece que você deseja responder a todas as suas exceções da mesma maneira ('Registre erros e envie-os por e-mail ao administrador em produção'). Se for esse o caso, sua opção mais simples é adicionar código ao
Application_Error (remetente do objeto, EventArgs e)
no seu global.asax. É aqui que você pode passar para a estrutura de log escolhida.
Se você deseja ter mais controle sobre o registro / tratamento de exceções, pode subclassificar HandleErrorAttribute e substituir
esse é outro lugar onde você pode passar para a estrutura de log escolhida.
https://stackoverflow.com/questions/183316/asp-net-mvc-handleerror
Isso lhe dá mais controle do que a técnica Application_Error mencionada acima.
Em geral, o MVC oferece uma grande granularidade de controle sobre como lidar com erros. Se você não precisar desse controle, poderá recorrer às maneiras de executar o ASP.net, como definir páginas de erro no seu web.config.
fonte