Réponse rapide / TL; DR
Pour les paresseux:
Install-Package MagicalUnicornMvcErrorToolkit -Version 1.0
Supprimez ensuite cette ligne de global.asax
GlobalFilters.Filters.Add(new HandleErrorAttribute());
Et ce n'est que pour IIS7 + et IIS Express.
Si vous utilisez Cassini ... eh bien ... euh ... euh ... maladroit ...
Réponse longue et expliquée
Je sais que cela a été répondu. Mais la réponse est VRAIMENT SIMPLE (bravo à David Fowler et Damian Edwards pour avoir vraiment répondu à cela).
Il n'est pas nécessaire de faire quoi que ce soit de personnalisé .
Car ASP.NET MVC3
, tous les morceaux sont là.
Étape 1 -> Mettez à jour votre web.config en DEUX spots.
<system.web>
<customErrors mode="On" defaultRedirect="/ServerError">
<error statusCode="404" redirect="/NotFound" />
</customErrors>
et
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" path="/NotFound" responseMode="ExecuteURL" />
<remove statusCode="500" subStatusCode="-1" />
<error statusCode="500" path="/ServerError" responseMode="ExecuteURL" />
</httpErrors>
...
<system.webServer>
...
</system.web>
Maintenant, prenez bien note des ITINÉRAIRES que j'ai décidé d'utiliser. Vous pouvez utiliser n'importe quoi, mais mes itinéraires sont
/NotFound
<- pour un 404 introuvable, page d'erreur.
/ServerError
<- pour toute autre erreur, incluez les erreurs qui se produisent dans mon code. il s'agit d'une erreur de 500 serveurs internes
Voyez comment la première section <system.web>
ne contient qu'une seule entrée personnalisée? L' statusCode="404"
entrée? Je n'ai répertorié qu'un seul code d'état, car toutes les autres erreurs, y compris 500 Server Error
(c.-à-d. Ces erreurs embêtantes qui se produisent lorsque votre code a un bogue et plante la demande de l'utilisateur) .. toutes les autres erreurs sont gérées par le paramètre defaultRedirect="/ServerError"
.. qui dit , si vous n'êtes pas une page 404 introuvable, alors veuillez vous rendre sur l'itinéraire /ServerError
.
D'accord. c'est à l'écart .. maintenant à mes itinéraires répertoriés dansglobal.asax
Étape 2 - Création des itinéraires dans Global.asax
Voici ma section complète de l'itinéraire ..
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{*favicon}", new {favicon = @"(.*/)?favicon.ico(/.*)?"});
routes.MapRoute(
"Error - 404",
"NotFound",
new { controller = "Error", action = "NotFound" }
);
routes.MapRoute(
"Error - 500",
"ServerError",
new { controller = "Error", action = "ServerError"}
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new {controller = "Home", action = "Index", id = UrlParameter.Optional}
);
}
Cela répertorie deux routes ignorées -> axd's
et favicons
(ooo! Bonus ignore route, pour vous!) Ensuite (et la commande est IMPERATIVE ICI), j'ai mes deux routes explicites de gestion des erreurs .. suivies de toutes les autres routes. Dans ce cas, celui par défaut. Bien sûr, j'en ai plus, mais c'est spécial pour mon site Web. Assurez-vous simplement que les routes d'erreur sont en haut de la liste. L'ordre est impératif .
Enfin, pendant que nous sommes à l'intérieur de notre global.asax
fichier, nous n'enregistrons PAS globalement l'attribut HandleError. Non, non, non monsieur. Nadda. Nan. Nien. Négatif. Noooooooooo ...
Supprimer cette ligne de global.asax
GlobalFilters.Filters.Add(new HandleErrorAttribute());
Étape 3 - Créez le contrôleur avec les méthodes d'action
Maintenant .. nous ajoutons un contrôleur avec deux méthodes d'action ...
public class ErrorController : Controller
{
public ActionResult NotFound()
{
Response.StatusCode = (int)HttpStatusCode.NotFound;
return View();
}
public ActionResult ServerError()
{
Response.StatusCode = (int)HttpStatusCode.InternalServerError;
// Todo: Pass the exception into the view model, which you can make.
// That's an exercise, dear reader, for -you-.
// In case u want to pass it to the view, if you're admin, etc.
// if (User.IsAdmin) // <-- I just made that up :) U get the idea...
// {
// var exception = Server.GetLastError();
// // etc..
// }
return View();
}
// Shhh .. secret test method .. ooOOooOooOOOooohhhhhhhh
public ActionResult ThrowError()
{
throw new NotImplementedException("Pew ^ Pew");
}
}
Ok, voyons ça. Tout d'abord, il n'y a AUCUN [HandleError]
attribut ici. Pourquoi? Parce que le ASP.NET
framework intégré gère déjà les erreurs ET nous avons spécifié toute la merde que nous devons faire pour gérer une erreur :) C'est dans cette méthode!
Ensuite, j'ai les deux méthodes d'action. Rien de difficile là-bas. Si vous souhaitez afficher des informations d'exception, vous pouvez les utiliser Server.GetLastError()
pour obtenir ces informations.
Bonus WTF: Oui, j'ai fait une troisième méthode d'action, pour tester la gestion des erreurs.
Étape 4 - Créez les vues
Et enfin, créez deux vues. Mettez-les dans la vue normale, pour ce contrôleur.
Commentaires bonus
- Vous n'avez pas besoin d'un
Application_Error(object sender, EventArgs e)
- Les étapes ci-dessus fonctionnent toutes à 100% parfaitement avec Elmah . Elmah bat des wrox!
Et ça, mes amis, ça devrait être ça.
Maintenant, félicitations pour avoir lu autant et avoir une licorne comme prix!