Szybka odpowiedź / TL; DR
Dla leniwych ludzi:
Install-Package MagicalUnicornMvcErrorToolkit -Version 1.0
Następnie usuń ten wiersz z global.asax
GlobalFilters.Filters.Add(new HandleErrorAttribute());
Dotyczy to tylko IIS7 + i IIS Express.
Jeśli używasz Cassini ... cóż ... hmm ... niezręcznie ...
Długa, wyjaśniona odpowiedź
Wiem, że na to odpowiedziano. Ale odpowiedź jest NAPRAWDĘ PROSTA (wiwaty dla Davida Fowlera i Damiana Edwardsa za naprawdę udzielenie odpowiedzi).
Nie trzeba robić nic niestandardowego .
Dla ASP.NET MVC3
wszystkie bity są tam.
Krok 1 -> Zaktualizuj swój plik web.config w DWÓCH miejscach.
<system.web>
<customErrors mode="On" defaultRedirect="/ServerError">
<error statusCode="404" redirect="/NotFound" />
</customErrors>
i
<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>
Teraz zwróć uwagę na TRASY, które zdecydowałem się użyć. Możesz użyć wszystkiego, ale moje trasy są
/NotFound
<- dla 404 nie znaleziono, strona błędu.
/ServerError
<- w przypadku każdego innego błędu dołącz błędy, które występują w moim kodzie. jest to wewnętrzny błąd serwera 500
Zobacz, jak pierwsza sekcja <system.web>
ma tylko jeden wpis niestandardowy? statusCode="404"
Wpis? Wymieniłem tylko jeden kod stanu, ponieważ wszystkie inne błędy, w tym 500 Server Error
(np. Te brzydkie błędy, które występują, gdy kod zawiera błąd i powoduje awarię żądania użytkownika) .. wszystkie pozostałe błędy są obsługiwane przez ustawienie defaultRedirect="/ServerError"
.. które mówi , jeśli nie znaleziono strony 404, proszę przejść do trasy /ServerError
.
Ok. to jest na uboczu .. teraz do moich tras wymienionych wglobal.asax
Krok 2 - Tworzenie tras w Global.asax
Oto mój pełny odcinek trasy ..
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}
);
}
To pokazuje dwie trasy ignorowania -> axd's
i favicons
(ooo! Bonus ignoruj trasę, dla ciebie!) Następnie (i kolejność jest IMPERATIVE TUTAJ), mam dwie wyraźne trasy obsługi błędów .. a następnie wszelkie inne trasy. W takim przypadku domyślny. Oczywiście mam ich więcej, ale jest to coś specjalnego na mojej stronie. Upewnij się tylko, że trasy błędów znajdują się na górze listy. Porządek jest konieczny .
Wreszcie, gdy jesteśmy w naszym global.asax
pliku, NIE rejestrujemy globalnie atrybutu HandleError. Nie, nie, nie proszę pana. Nadda Nie. Nien. Negatywny. Nieeeeeeee ...
Usuń tę linię z global.asax
GlobalFilters.Filters.Add(new HandleErrorAttribute());
Krok 3 - Utwórz kontroler za pomocą metod działania
Teraz .. dodajemy kontroler z dwiema metodami działania ...
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, sprawdźmy to. Przede wszystkim, nie ma NO [HandleError]
atrybut tutaj. Dlaczego? Ponieważ wbudowanyASP.NET
platforma już obsługuje błędy ORAZ określiliśmy wszystkie gówna, które musimy zrobić, aby obsłużyć błąd :) Jest w tej metodzie!
Następnie mam dwie metody działania. Nic trudnego. Jeśli chcesz wyświetlić informacje o wyjątku, możesz użyć Server.GetLastError()
tej informacji.
Dodatkowy WTF: Tak, podjąłem trzecią metodę działania, aby przetestować obsługę błędów.
Krok 4 - Utwórz widoki
Na koniec utwórz dwa widoki. Umieść je w normalnym miejscu widoku dla tego kontrolera.
Komentarze do bonusów
- Nie potrzebujesz
Application_Error(object sender, EventArgs e)
- Powyższe kroki działają w 100% idealnie z Elmah . Elmah piekący wokry!
I to, moi przyjaciele, powinno być to.
Gratulacje za przeczytanie tak dużo i zdobycie Jednorożca jako nagrody!