Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch 404 Error in MVC4

I have an problem cacting the HTTP Error 404.0 - Not Found. I have turned on the

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

in the Web.Config. But the problem still exist. I have 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();

    }
like image 214
mortenstarck Avatar asked Mar 04 '13 14:03

mortenstarck


People also ask

How to handle 404 Error in asp net c#?

A simple solution is to check for the HTTP status code 404 in the response. If found, you can redirect the control to a page that exists. The following code snippet illustrates how you can write the necessary code in the Configure method of the Startup class to redirect to the home page if a 404 error has occurred. });


2 Answers

Okay i found an solution thanks to @alistair-findlay and this website. This is how the 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 the 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 lastly:

 public class ErrorController : Controller
  {

    public ActionResult HttpError403(string error)
    {
      ViewBag.Description = error;
      return this.View();
    }
like image 77
mortenstarck Avatar answered Nov 20 '22 15:11

mortenstarck


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

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

    public ActionResult HttpError404()
    {
        return View();
    }

    public ActionResult HttpError500()
    {
        return View();
    }
}

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

In terms of logging the error, you would 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 to "catch" the error before the 302 redirect to your Error pages defined in the ErrorController above.

like image 37
Alistair Findlay Avatar answered Nov 20 '22 17:11

Alistair Findlay