Risposta rapida / TL; DR
Per le persone pigre là fuori:
Install-Package MagicalUnicornMvcErrorToolkit -Version 1.0
Quindi rimuovere questa riga da global.asax
GlobalFilters.Filters.Add(new HandleErrorAttribute());
E questo è solo per IIS7 + e IIS Express.
Se stai usando Cassini .. beh .. um .. er .. imbarazzante ...
Risposta lunga e spiegata
So che è stata data una risposta. Ma la risposta è DAVVERO SEMPLICE (saluti a David Fowler e Damian Edwards per aver davvero risposto a questa domanda).
Non è necessario fare nulla di personalizzato .
Perché ASP.NET MVC3
, tutti i pezzi ci sono.
Passaggio 1:> Aggiorna web.config in DUE spot.
<system.web>
<customErrors mode="On" defaultRedirect="/ServerError">
<error statusCode="404" redirect="/NotFound" />
</customErrors>
e
<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>
Ora prendi nota degli ITINERARI che ho deciso di utilizzare. Puoi usare qualsiasi cosa, ma i miei percorsi lo sono
/NotFound
<- per un 404 non trovato, pagina di errore.
/ServerError
<- per qualsiasi altro errore, includi gli errori che si verificano nel mio codice. questo è un errore del server interno 500
Vedi come la prima sezione in <system.web>
ha solo una voce personalizzata? La statusCode="404"
voce? Ho elencato un solo codice di stato perché tutti gli altri errori, incluso il 500 Server Error
(cioè quegli fastidiosi errori che si verificano quando il tuo codice ha un bug e si blocca la richiesta dell'utente) .. tutti gli altri errori sono gestiti dall'impostazione defaultRedirect="/ServerError"
.. che dice , se non sei una pagina 404 non trovata, vai al percorso/ServerError
.
Ok. questo è fuori mano .. ora per i miei percorsi elencati inglobal.asax
Passaggio 2: creazione dei percorsi in Global.asax
Ecco la mia sezione del percorso completo ..
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}
);
}
Questo elenca due percorsi ignorati -> axd's
e favicons
(ooo! Bonus ignora percorso, per te!) Quindi (e l'ordine è IMPERATIVO QUI), ho i miei due percorsi espliciti di gestione degli errori .. seguiti da qualsiasi altro percorso. In questo caso, quello predefinito. Certo, ne ho di più, ma è speciale per il mio sito web. Assicurati solo che i percorsi di errore siano in cima all'elenco. L'ordine è imperativo .
Infine, mentre siamo all'interno del nostro global.asax
file, NON registriamo globalmente l'attributo HandleError. No, no, no signore. Nadda. No. Nien. Negativo. Noooooooooo ...
Rimuovi questa linea da global.asax
GlobalFilters.Filters.Add(new HandleErrorAttribute());
Passaggio 3: creare il controller con i metodi di azione
Ora .. aggiungiamo un controller con due metodi di azione ...
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, diamo un'occhiata. Prima di tutto, NON esiste alcun [HandleError]
attributo qui. Perché? Perché il ASP.NET
framework integrato sta già gestendo gli errori E abbiamo specificato tutta la merda che dobbiamo fare per gestire un errore :) È in questo metodo!
Successivamente, ho i due metodi di azione. Niente di difficile lì. Se desideri mostrare informazioni sull'eccezione, puoi utilizzarle Server.GetLastError()
per ottenere tali informazioni.
Bonus WTF: Sì, ho realizzato un terzo metodo di azione per testare la gestione degli errori.
Passaggio 4: creare le viste
E infine, creare due viste. Mettili nel normale punto di vista, per questo controller.
Commenti bonus
- Non hai bisogno di un
Application_Error(object sender, EventArgs e)
- I passaggi precedenti funzionano perfettamente al 100% con Elmah . Elmah sfilaccia i guai!
E quello, amici miei, dovrebbe essere.
Ora, congratulazioni per aver letto così tanto e avere un Unicorno come premio!