J'ai eu du mal toute la journée à mettre en œuvre la gestion des erreurs dans mon application ASP.NET MVC 2. J'ai étudié plusieurs techniques, mais aucune ne fonctionne correctement. J'utilise MVC2 et .NET 4.0 (j'ai commencé le projet avant la sortie de MVC3 ; nous ferons la mise à jour après la livraison de notre première version).
À ce stade, je serais heureux de gérer correctement les erreurs 404 et 500 -- un 403 (autorisation requise) serait génial aussi, suivi de diverses autres réponses spécifiques. Actuellement, je reçois soit toutes les 404, toutes les 500, toutes les 302 avant la 404, ou toutes les 302 avant la 500.
Voici mes exigences (qui devraient être assez proches des exigences de base de HTTP) :
-
Si une ressource n'est pas trouvée, renvoyer un 404, et afficher une page spécifique au 404 avec l'URL demandée. NE PAS renvoyer un code de réponse intermédiaire comme un 302. Idéalement, conserver l'URL demandée, plutôt que d'afficher une nouvelle URL comme
/Error/NotFound
-- mais si cette dernière s'affiche, assurez-vous que nous n'avons pas renvoyé de réponse de redirection pour l'obtenir. -
Si une erreur interne du serveur s'est produite, renvoyer un 500, et afficher une erreur spécifique au 500 avec une indication de ce qui s'est mal passé. Encore une fois, ne renvoyez pas de code de réponse intermédiaire, et idéalement ne modifiez pas l'URL.
Voici ce que je considérerais comme un 404 :
- Fichier statique introuvable :
/Contenu/non-existent-dir/non-existent-file.txt
- Contrôleur introuvable :
/non-existent-controller/Foo/666
- Contrôleur trouvé, mais action introuvable :
/Accueil/non-existent-action/666
- Contrôleur et action trouvés, mais l'action ne peut pas trouver l'objet demandé :
/Accueil/Connexion/non-existent-id
Voici ce que je considérerais comme un 500 :
- Postez une mauvaise valeur :
POST /Utilisateur/Nouveau/nom-d-utilisateur-trop-long-pour-la-contrainte-de-colonne-db
- Problème non lié aux données, comme un point de terminaison de service Web qui ne répond pas
Certains de ces problèmes doivent être identifiés par des contrôleurs ou des modèles spécifiques, puis les contrôleurs doivent déclencher les HttpException appropriées. Le reste devrait être traité de manière plus générique.
Pour le cas 404 n°2, j'ai essayé d'utiliser une Factory de contrôleurs personnalisée pour renvoyer un 404 si le contrôleur ne peut pas être trouvé. Pour le cas 404 n°3, j'ai essayé d'utiliser un contrôleur de base personnalisé pour remplacer HandleUnknownAction
et renvoyer un 404.
Dans les deux cas, je reçois un 302 avant le 404. Et, je ne reçois jamais d'erreurs 500 ; si je modifie Web.config pour mettre une erreur de frappe dans mon point de terminaison de service Web, je reçois toujours un 302, puis un 404 disant que l'URL (contrôleur/action) qui utilise le service Web ne peut pas être trouvé. Je reçois également l'URL demandée comme paramètre de chaîne de requête (non désiré) : /Error/NotFound?aspxerrorpath=/Accueil/non-existent-action
Les deux techniques viennent de http://www.niksmit.com/wp/?p=17 (Comment obtenir des pages d'erreur 404 normales (Page non trouvée) avec ASP.Net MVC), mentionnées sur http://richarddingwall.name/2008/08/17/strategies-for-resource-based-404-errors-in-aspnet-mvc/
Si dans Web.config j'ai , je reçois le code de réponse approprié, mais mon contrôleur d'erreur n'est jamais appelé. En retirant l'attribut redirectMode
, je reçois les vues d'erreur MVC, mais avec un 302 intermédiaire et une URL modifiée -- et toujours le même contrôleur (Unknown
= 500 ; si je le change en NotFound
tout semble être un 404).
Voici quelques-unes des autres choses que j'ai lues et essayé de mettre en œuvre :
- http://www.davidjuth.com/asp-net-mvc-error-handler.aspx
- http://sanjayuttam.com/wordpress/index.php/c-sharp/c-sharp-code-examples/error-handling-in-asp-net-mvc-1-part-2-of-2/
- http://blog.hebbink.com/post/2010/12/14/NET-custom-404-error-page-returns-302-for-http-status.aspx
- http://blog.dantup.com/2009/04/aspnet-mvc-handleerror-attribute-custom.html
- http://weblogs.asp.net/scottgu/archive/2008/07/14/asp-net-mvc-preview-4-release-part-1.aspx
.. ainsi qu'une multitude de publications sur StackOverflow.
Il me semble que ce type de gestion des erreurs est assez fondamental pour les applications Web, et le framework MVC devrait avoir des configurations par défaut qui le font automatiquement, et permettent aux gens de l'étendre pour qu'il fonctionne différemment. Peut-être le feront-ils dans une future version. En attendant, quelqu'un peut-il me donner des détails complets sur comment implémenter correctement les réponses HTTP ?