Le processus de gestion des erreurs personnalisé dans ASP.NET MVC (3 dans ce cas) semble être incroyablement négligé. J'ai lu les différentes questions et réponses ici, sur le Web, les pages d'aide pour divers outils (comme Elmah), mais j'ai l'impression d'avoir fait un cercle complet et je n'ai toujours pas la meilleure solution. Avec votre aide, nous pouvons peut-être définir une nouvelle approche standard pour la gestion des erreurs. Je voudrais garder les choses simples et ne pas trop l'ingénier.
Voici mes objectifs:
Pour les erreurs/exceptions du serveur:
Pour les erreurs 404 non trouvées:
Existe-t-il un moyen d'atteindre ces objectifs avec ASP.NET MVC?
Je vais partager la façon dont j'ai fini par le faire, cela faisait partie de la question initiale.
Tout d'abord, les problèmes que j'ai rencontrés:
Lorsque customErrors est activé (c.-à-d. En production), l'attribut global HandleError
avale les exceptions et affiche votre vue d'erreur, mais vous ne pouvez pas le consigner avec un outil complémentaire comme elmah, car elmah ne le voit jamais. Vous pouvez l'enregistrer à votre avis, je suppose, mais c'est une vue qui semble erronée. L'attribut global HandleError apparaît nouveau dans le modèle de projet Visual Studio MVC 3 RTM.
customErrors avec des URL pour les points de terminaison MVC renvoie 302 codes d'état. Il existe la propriété redirectmode, mais vous ne pouvez pas faire correspondre les URL mvc dans customErrors et utiliser le mode ResponseRewrite. ( https://stackoverflow.com/questions/781861/customerrors-does-not-work-when-setting-redirectmode-responserewrite/3770265#3770265 )
Éviter complètement les erreurs personnalisées et gérer tout ce qui est personnalisé dans votre application conduit à beaucoup de complexité, IMO. (Il a aimé ceci: https://stackoverflow.com/questions/619895/how-can-i-properly-handle-404s-in-asp-net-mvc/2577095#2577095 , mais ce n'était pas pas bon pour notre projet)
Ma solution
J'ai complètement retiré MVC de l'équation. J'ai supprimé le filtre global HandleErrorAttribute
dans global.asax et je me concentre entièrement sur la configuration customErrors, en le déplaçant pour utiliser les redirections WebForm et en changeant de mode de redirection vers ResponseRewrite
afin d'éviter les 302 codes de réponse HTTP .
<customErrors mode="On" defaultRedirect="/Error.aspx" redirectMode="ResponseRewrite">
<error statusCode="404" redirect="/NotFound.aspx" />
</customErrors>
Puis dans NotFound.aspx
événement page_load, définissez Response.StatusCode
à 404 et dans Error.aspx, définissez le code 500.
Résultats:
Les objectifs pour les deux ont été atteints avec les journaux Elmah, la page d'erreur conviviale et le code d'état avec une ligne de code sur les codes derrière. Nous ne le faisons pas de la manière "MVC" comme le fait la solution précédente, mais je suis d'accord avec ça s'il s'agit de deux lignes de code.
Je pense que MVC, ASP et votre framework de journalisation/gestion des exceptions préféré peuvent très bien gérer vos objectifs. ELMAH et Enterprise Library offrent tous deux une gestion et une journalisation des exceptions faciles à utiliser, alors choisissez votre favori .. I je ne vais pas entrer dans les avantages et les inconvénients de chacun ici.
REMARQUE: vous ne pouvez pas afficher une page d'erreur conviviale ET renvoyer un HTTP 404 ou 500 comme le suggère votre question. Lorsque vous renvoyez une page d'erreur conviviale, le code HTTP renvoyé à votre navigateur est 302. Il s'agit d'une redirection vers la page d'erreur conviviale.
Il semble que vous puissiez atteindre vos objectifs grâce aux bons paramètres web.config façonnés qui font partie d'ASP.net depuis un certain temps. Vous mentionnez afficher des informations de débogage en développement et afficher des pages conviviales en production. Vous pouvez utiliser la section des erreurs personnalisées du web.config pour cela (Set CustomErrors = "Off" pour afficher les informations de débogage). Je vais supposer que vous connaissez bien l'attribut CustomErrors, sinon lisez ceci:
http://msdn.Microsoft.com/en-us/library/h0hfz6fc.aspx
Si vous avez besoin d'une plus grande granularité de contrôle sur les vues d'erreur que vous affichez, utilisez l'attribut HandleError de MVC. De cette façon, vous pouvez choisir différentes vues d'erreur pour chaque action/contrôleur.
http://weblogs.asp.net/scottgu/archive/2008/07/14/asp-net-mvc-preview-4-release-part-1.aspx
Il semble que vous souhaitiez répondre à toutes vos exceptions de la même manière ("Consigner les erreurs et les envoyer par e-mail à l'administrateur en production"). Si tel est le cas, votre option la plus simple consiste à ajouter du code à
Application_Error (expéditeur d'objet, EventArgs e)
dans votre global.asax. C'est là que vous pouvez passer à votre infrastructure de journalisation choisie.
Si vous voulez plus de contrôle sur la journalisation/gestion des exceptions, vous pouvez sous-classer HandleErrorAttribute et remplacer
OnException(System.Web.Mvc.ExceptionContext filterContext)
c'est un autre endroit où vous pouvez passer à votre cadre de journalisation choisi.
https://stackoverflow.com/questions/183316/asp-net-mvc-handleerror
Cela vous donne plus de contrôle que la technique Application_Error mentionnée ci-dessus.
En général, MVC vous donne une grande granularité de contrôle sur la façon de gérer les erreurs. Si vous n'avez pas besoin de ce contrôle, vous pouvez vous rabattre sur les façons de faire ASP.net, telles que la définition de pages d'erreur sur votre web.config.