Catch 404 error in MVC4

I have a problem with HTTP 404.0 response - Not Found. I turned on

<customErrors mode="On" defaultRedirect="~/Error/General"> <error statusCode="404" redirect="~/Error/HttpError404" /> <error statusCode="500" redirect="~/Error/HttpError500" /> </customErrors> 

in Web.Config. But the problem still exists. I also tried this solution (but it never reaches the method):

 protected void Application_Error() { var exception = Server.GetLastError(); var httpException = exception as HttpException; Response.Clear(); Server.ClearError(); var routeData = new RouteData(); routeData.Values["controller"] = "Errors"; routeData.Values["action"] = "General"; routeData.Values["exception"] = exception; Response.StatusCode = 500; if (httpException != null) { Response.StatusCode = httpException.GetHttpCode(); switch (Response.StatusCode) { case 403: routeData.Values["action"] = "HttpError404"; break; case 404: routeData.Values["action"] = "HttpError404"; break; } } IController errorsController = new ErrorController(); var rc = new RequestContext(new HttpContextWrapper(Context), routeData); errorsController.Execute(rc); } 

provided by @Darin Dimitrov

This is the controller:

 public class ErrorController : Controller { public ActionResult HttpError404(string error) { ViewData["Title"] = "Sorry, an error occurred while processing your request. (404)"; ViewData["Description"] = error; return View("Index"); } public ActionResult HttpError500(string error) { ViewData["Title"] = "Sorry, an error occurred while processing your request. (500)"; ViewData["Description"] = error; return View("Index"); } public ActionResult General(string error) { ViewData["Title"] = "Sorry, an error occurred while processing your request."; ViewData["Description"] = error; return this.View(); } 
+7
source share
2 answers

Ok, I found a solution thanks to @ alistair-findlay and this website . Here's what web.config looks like now:

 <system.web> <customErrors mode="On" defaultRedirect="~/Error/General" redirectMode="ResponseRewrite"> </customErrors> </system.web> <system.webServer> <httpErrors errorMode="Detailed" defaultResponseMode="Redirect"> <clear/> <error statusCode="404" path="/Error/HttpError404"/> </httpErrors> </system.webServer 

And this is Global.asax.cs:

  protected void Application_Error() { if (Context.IsCustomErrorEnabled) ShowCustomErrorPage(Server.GetLastError()); } private void ShowCustomErrorPage(Exception exception) { var httpException = exception as HttpException ?? new HttpException(500, "Internal Server Error", exception); Response.Clear(); var routeData = new RouteData(); routeData.Values.Add("controller", "Error"); routeData.Values.Add("fromAppErrorEvent", true); switch (httpException.GetHttpCode()) { case 403: routeData.Values.Add("action", "HttpError403"); break; case 404: routeData.Values.Add("action", "HttpError404"); break; case 500: routeData.Values.Add("action", "HttpError500"); break; default: routeData.Values.Add("action", "GeneralError"); routeData.Values.Add("httpStatusCode", httpException.GetHttpCode()); break; } Server.ClearError(); IController controller = new ErrorController(); controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData)); } 

And finally:

  public class ErrorController : Controller { public ActionResult HttpError403(string error) { ViewBag.Description = error; return this.View(); } 
+11
source

Have you implemented an ErrorController that handles redirects in your customErrors attributes? In your case, it will look something like this:

 public class ErrorController : Controller { public ActionResult General() { return View(); } public ActionResult HttpError404() { return View(); } public ActionResult HttpError500() { return View(); } } 

You will also need to implement views for each of the ActionResults in the Views folder.

In terms of registering errors, you need to implement this in the Application_Error event handler as follows:

 protected void Application_Error() { var exception = Server.GetLastError(); var httpException = exception as HttpException; // Do logging here } 

This is necessary to β€œcatch” the error before redirecting 302 to your error pages defined in the ErrorController above.

+1
source

All Articles