39

We want to handle 403 errors, 404 errors, all errors due to a MySpecialDomainException and provide a default error page for all other errors (including errors in the IIS configuration!). All errors should return proper Razor views, it would be very nice to have an ErrorController in front of the views. E.g. something like this:

public class ErrorController : Controller
{
    public ViewResult NotFound () { return View(); }
    public ViewResult Forbidden () { return View(); }
    public ViewResult Default ()
    {
        var ex = ObtainExceptionFromSomewhere();
        if(ex is MySpecialDomainException)
            return View("MySpecialDomainException", new ErrorModel { Exception = ex });

        return View("GeneralError", new ErrorModel { Exception = ex });
    }
}

Currently you find many different ways to do that on the www, some most probably outdated. Among those:

  • Controller.OnException()
  • Error filter
  • customErrors element in web.config
  • Handling in Global.asax's Application_Error

Q1: What is the recommended way to fulfill our requirements with ASP.NET MVC 5?

Also we want to catch errors occurring in the IIS host. Q2: To prevent that IIS has to handle any 404s we thought about adding a default route matching all possible URLs - is this recommendable? Better to register instead for IIS' 404s as well?

Q3: Is it even possible to register an IIS error page which goes back to a controller, or is IIS capable of ASPX / static HTML only?

Mukesh Ram
  • 6,248
  • 4
  • 19
  • 37
D.R.
  • 20,268
  • 21
  • 102
  • 205
  • I'm curious.. How exactly would you propose to have Razor pages when IIS is not configured correctly? If IIS isn't working, Razor won't be working... – Erik Funkenbusch Feb 24 '14 at 16:51
  • Yeah, probably it is not even possible. Maybe we have to settle for a static HTML @ IIS. So probably its best to cover all possible URLs with ASP.NET MVC in order to prevent 404's bubbling up to IIS... – D.R. Feb 24 '14 at 16:53
  • http://www.codeproject.com/Articles/850062/Exception-handling-in-ASP-NET-MVC-methods-explaine – NoWar Sep 20 '16 at 13:21
  • 2
    https://dusted.codes/demystifying-aspnet-mvc-5-error-pages-and-error-logging – GANI Sep 26 '16 at 19:38
  • The Microsoft page @Liam provided is more appropriate for Web Forms than MVC. – Mike Grove aka Theophilus Oct 11 '19 at 21:13

3 Answers3

56

The best way is using Global.Asax, because you can manage all types of errors (Ajax calls/ all of unexpected Errors). with others you can't do it.

Like this:

protected void Application_Error()
{
    HttpContext httpContext = HttpContext.Current;
    if (httpContext != null)
    {
        RequestContext requestContext = ((MvcHandler)httpContext.CurrentHandler).RequestContext;
        /* When the request is ajax the system can automatically handle a mistake with a JSON response. 
           Then overwrites the default response */
        if (requestContext.HttpContext.Request.IsAjaxRequest())
        {
            httpContext.Response.Clear();
            string controllerName = requestContext.RouteData.GetRequiredString("controller");
            IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();
            IController controller = factory.CreateController(requestContext, controllerName);
            ControllerContext controllerContext = new ControllerContext(requestContext, (ControllerBase)controller);

            JsonResult jsonResult = new JsonResult
            {
                Data = new { success = false, serverError = "500" },
                JsonRequestBehavior = JsonRequestBehavior.AllowGet
            };
            jsonResult.ExecuteResult(controllerContext);
            httpContext.Response.End();
        }
        else
        {
            httpContext.Response.Redirect("~/Error");
        }
    }
}
radbyx
  • 9,352
  • 21
  • 84
  • 127
natnael88
  • 1,128
  • 10
  • 22
  • how can i get error code to pass as dynamic in ServerError="500" or other – Heemanshu Bhalla Aug 18 '16 at 08:15
  • Application_Error is handled just when you have unexpected exception in your code, so this means by default your response result will be always 500(Internal Server Error). But if you'd like to change the error code, you can create custom exceptions in your code and in base of Error Exception you got you can set the Error code you want... – natnael88 Aug 18 '16 at 16:28
  • why my response result will always be 500 . Oh I think i think I missed one thing . Application_Error will be invoked only if there is any Exception it will be not invoked in case of 404 errors .---------i think its better to use web.config for 404 errors – Heemanshu Bhalla Aug 19 '16 at 08:03
  • 1
    Sorry you are right.., You can manage everything unexpected error in your MVC Page,is not just 500(of course if you have Code Exception is always 500(Internal Server Error)). this is the code : HttpException serverError = Server.GetLastError() as HttpException; if (serverError !=null) { int errorCode = serverError.GetHttpCode(); } – natnael88 Aug 19 '16 at 10:24
  • Note that with this solution, all AJAX calls (including calling nonexistent endpoints) will apparently succeed. You will need to unwrap the response data to handle failures. – StuartN Oct 27 '17 at 11:37
41

There is no golden solution to all applications.

You can display a friendly error page by using httpErrors in web.config. Unlike customErrors this is an IIS level setting and will even show you a friendly error page for errors which are not from within ASP.NET.

For error logging I would recommend to go with a HttpModule like ELMAH: https://code.google.com/p/elmah/

I wrote a whole blog post about this and where I explain the different ways of error handling: http://dusted.codes/demystifying-aspnet-mvc-5-error-pages-and-error-logging

dustinmoris
  • 3,195
  • 3
  • 25
  • 33
  • 1
    Literally the second paragraph "You can display..." answers directly the question. In contrast there is no list of links. There are only 2 links - the first a link directly to a commonly used tool in ASP.NET for error logging and the second to a lengthy blog post elaborating a lot more on this topic, but even more than what has been asked here. I don't see any harm in including this. Thanks for trolling though. – dustinmoris Apr 12 '17 at 14:16
7

Better way of handling error is extending handleerror attribute. Handle error attribute has following advantages

  • With HandleErrorAttribute we get more control over exception handling. HandleError allow us to handle error differently for different controllers and actions easily where in Application_Error to get this feature we take the help of switch loop.

  • Once you are into Application_Error you are out of MVC and you will lose ControllerContext and then we cannot do much things which will easily possible with HandleError.

see the following post for how to extend error handling attribute and advantages

Advantages of [HandleError] over Application_Error

http://maheshde.blogspot.com.au/2012/09/error-handing-with-mvc-using-custom.html

http://www.codeproject.com/Articles/731913/Exception-Handling-in-MVC

Community
  • 1
  • 1
Mahesh
  • 2,731
  • 2
  • 32
  • 31
  • Thanks for this Mahesh! I've left a comment on your blog (https://maheshde.blogspot.com.au/2012/09/error-handing-with-mvc-using-custom.html?showComment=1511493570513) as I'd like to know how to intercept 500 errors and under certain conditions repackage as a 404. – mattpm Nov 24 '17 at 03:22