Tworzę witrynę bazową MVC3 i szukam rozwiązania do obsługi błędów i renderowania niestandardowych widoków dla każdego rodzaju błędu. Wyobraź sobie więc, że mam kontroler „Error”, którego główną akcją jest „Index” (ogólna strona błędu), a ten kontroler będzie miał jeszcze kilka akcji dla błędów, które mogą pojawić się użytkownikowi, jak „Handle500” lub „HandleActionNotFound”.
Tak więc każdy błąd, który może wystąpić na stronie internetowej, może zostać obsłużony przez ten kontroler „Błąd” (przykłady: „Nie znaleziono kontrolera” lub „Akcji”, 500, 404, wyjątek dbException, itp.).
Używam pliku mapy witryny do definiowania ścieżek witryny (a nie trasy).
Na to pytanie już odpowiedziano, to jest odpowiedź dla Gweebz
Moja ostatnia metoda applicaiton_error jest następująca:
protected void Application_Error() {
//while my project is running in debug mode
if (HttpContext.Current.IsDebuggingEnabled && WebConfigurationManager.AppSettings["EnableCustomErrorPage"].Equals("false"))
{
Log.Logger.Error("unhandled exception: ", Server.GetLastError());
}
else
{
try
{
var exception = Server.GetLastError();
Log.Logger.Error("unhandled exception: ", exception);
Response.Clear();
Server.ClearError();
var routeData = new RouteData();
routeData.Values["controller"] = "Errors";
routeData.Values["action"] = "General";
routeData.Values["exception"] = exception;
IController errorsController = new ErrorsController();
var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
errorsController.Execute(rc);
}
catch (Exception e)
{
//if Error controller failed for same reason, we will display static HTML error page
Log.Logger.Fatal("failed to display error page, fallback to HTML error: ", e);
Response.TransmitFile("~/error.html");
}
}
}
źródło
Odpowiedzi:
Oto przykład, jak radzę sobie z niestandardowymi błędami. Definiuję
ErrorsController
z akcjami obsługującymi różne błędy HTTP:a następnie zapisuję się na
Application_Error
inGlobal.asax
i wywołuję ten kontroler:źródło
Execute
to metoda zdefiniowana wIController
interfejsie. To nie może być chronione. Przyjrzyj się uważniej mojemu kodowi:IController errorsController = new ErrorsController();
i zwróć uwagę na typerrorsController
zmiennej, dla której wywołujęExecute
metodę. Jest typowy,IController
więc nic nie stoi na przeszkodzie, aby wywołać tę metodę. Nawiasem mówiąc,Execute
był chroniony również w klasie Controller w MVC 3, więc nie ma zmiany w tym względzie.Response.ContentType = "text/html";
Oto więcej artykułów Jak tworzyć niestandardowe strony błędów za pomocą MVC http://kitsula.com/Article/MVC-Custom-Error-Pages .
źródło
Możesz to również zrobić w pliku Web.Config. Oto przykład, który działa w usługach IIS 7.5.
źródło
Widzę, że dodałeś wartość konfiguracyjną dla
EnableCustomErrorPage
i również sprawdzaszIsDebuggingEnabled
czy uruchomić obsługę błędów.Ponieważ istnieje już
<customErrors/>
konfiguracja w ASP.NET (która jest przeznaczona dokładnie do tego celu), najłatwiej jest po prostu powiedzieć:Następnie w konfiguracji, którą umieścisz,
<customErrors mode="RemoteOnly" />
która jest bezpieczna do wdrożenia w ten sposób, a kiedy chcesz przetestować niestandardową stronę błędu, ustaw ją na<customErrors mode="On" />
, abyś mógł sprawdzić, czy działa.Zauważ, że musisz również sprawdzić, czy
HttpContext.Current
jest null, ponieważ wyjątek wApplication_Start
nadal będzie używał tej metody, chociaż nie będzie aktywnego kontekstu.źródło
Możesz wyświetlić przyjazną dla użytkownika stronę błędu z poprawnym kodem statusu http, implementując moduł Przyjaznej dla użytkownika obsługi wyjątków Jeffa Atwooda z niewielką modyfikacją kodu statusu http. Działa bez przekierowań. Chociaż kod pochodzi z 2004 roku (!), Dobrze współpracuje z MVC. Można go całkowicie skonfigurować w pliku web.config, bez żadnych zmian w kodzie źródłowym projektu MVC.
Modyfikacja wymagana do zwrócenia oryginalnego stanu HTTP zamiast
200
statusu jest opisana w tym pokrewnym poście na forum .Zasadniczo w Handler.vb możesz dodać coś takiego:
źródło
Używam MVC 4.5 i miałem problemy z rozwiązaniem Darina. Uwaga: rozwiązanie Darina jest doskonałe i użyłem go do wymyślenia mojego rozwiązania. Oto moje zmodyfikowane rozwiązanie:
źródło