Opierając się na odpowiedzi opublikowanej przez maxspan, przygotowałem minimalny przykładowy projekt na GitHub pokazujący wszystkie działające części.
Zasadniczo po prostu dodajemy Application_Error
metodę do global.asax.cs, aby przechwycić wyjątek i dać nam możliwość przekierowania (lub bardziej poprawnie, żądania przeniesienia ) na niestandardową stronę błędu.
protected void Application_Error(Object sender, EventArgs e)
{
// See http://stackoverflow.com/questions/13905164/how-to-make-custom-error-pages-work-in-asp-net-mvc-4
// for additional context on use of this technique
var exception = Server.GetLastError();
if (exception != null)
{
// This would be a good place to log any relevant details about the exception.
// Since we are going to pass exception information to our error page via querystring,
// it will only be practical to issue a short message. Further detail would have to be logged somewhere.
// This will invoke our error page, passing the exception message via querystring parameter
// Note that we chose to use Server.TransferRequest, which is only supported in IIS 7 and above.
// As an alternative, Response.Redirect could be used instead.
// Server.Transfer does not work (see https://support.microsoft.com/en-us/kb/320439 )
Server.TransferRequest("~/Error?Message=" + exception.Message);
}
}
Kontroler błędów:
/// <summary>
/// This controller exists to provide the error page
/// </summary>
public class ErrorController : Controller
{
/// <summary>
/// This action represents the error page
/// </summary>
/// <param name="Message">Error message to be displayed (provided via querystring parameter - a design choice)</param>
/// <returns></returns>
public ActionResult Index(string Message)
{
// We choose to use the ViewBag to communicate the error message to the view
ViewBag.Message = Message;
return View();
}
}
Wyświetl stronę błędu:
<!DOCTYPE html>
<html>
<head>
<title>Error</title>
</head>
<body>
<h2>My Error</h2>
<p>@ViewBag.Message</p>
</body>
</html>
Nic innego nie jest zaangażowany, inne niż wyłączenie / usunięcie filters.Add(new HandleErrorAttribute())
w FilterConfig.cs
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//filters.Add(new HandleErrorAttribute()); // <== disable/remove
}
}
Chociaż jest bardzo prosty do wdrożenia, jedyną wadą, którą widzę w tym podejściu, jest użycie kwerendy do dostarczania informacji o wyjątkach do docelowej strony błędu.