1

I have a bit of code which performs error handling for me displaying particular views depending on the error received.

My code looks like this:

protected void Application_EndRequest()
    {
        var response = new HttpResponseMessage((HttpStatusCode)Context.Response.StatusCode);
        if (!response.IsSuccessStatusCode)
        {
            var rd = new RouteData();
            IController c = new ErrorController();
            switch (response.StatusCode)
            {
                case HttpStatusCode.BadRequest:
                    Response.Clear();
                    rd.Values["controller"] = "Error";
                    rd.Values["action"] = "BadRequest";
                    c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));
                    break;
                case HttpStatusCode.NotFound:
                    Response.Clear();
                    rd.Values["controller"] = "Error";
                    rd.Values["action"] = "NotFound";
                    c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));
                    break;
                case HttpStatusCode.InternalServerError:
                    Response.Clear();
                    rd.Values["controller"] = "Error";
                    rd.Values["action"] = "InternalServerError";
                    c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));
                    break;
                case HttpStatusCode.Forbidden:
                    Response.Clear();
                    rd.Values["controller"] = "Error";
                    rd.Values["action"] = "Forbidden";
                    c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));
                    break;
                default:
                    Response.Clear();
                    rd.Values["controller"] = "Error";
                    rd.Values["action"] = "GenericError";
                    c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));
                    break;
            }
        }

This works for standard http status codes and as defined in the documentation, and response code of 200-299 doesnt get handled and passes through.

However, my question is, is this the best way to do it?

This arose from one of my requests returning a status code of 302 - Found. Now, according to the documentation, this would not be classified as a successful code, however, i do not see how it cannot be classified as successful.

Therefore is there a better way to do this to account for all successful codes rather than just 200-299?

Many Thanks for any input and opinions. I understand there may not be an absolute answer to this.

Putting 1 suggestion out there would be to change the if statement to:

if(!(statuscode >= 400 && statuscode <= 599)

This is because 4xx codes are defined as client errors and 5xx codes are defined as server errors. Therefore it should catch them all??

But what to do about the dreaded 418? :)

EDIT

I have attempted using httpErrors:

<httpErrors errorMode="Custom" existingResponse="Replace">
    <clear/>
    <error path="/Error/NotFound" responseMode="ExecuteURL" statusCode="400"/>
</httpErrors>

As well as customErrors in web.config:

<customErrors mode="On" defaultRedirect="~/Error"> 
    <error statusCode="404" redirect="~/Error/NotFound" /> 
    <error statusCode="403" redirect="~/Error/Forbidden" /> 
    <error statusCode="500" redirect="~/Error/InternalServerError" />        
</customErrors>

Both with no luck

DaRoGa
  • 2,196
  • 8
  • 34
  • 62

2 Answers2

1

You don't necessarily need to cover all error codes (from 400 to 500).

Have a look at: Which HTTP Status Codes to cover for MVC error handling

And it's better to use the handlers already in the pipeline instead of what you are doing in Application_EndRequest(). What I mean by that is that you should use the <httpErrors ... and/or <customErrors in the web.config.

<httpErrors> configures IIS, while <customErrors> configures ASP.NET Source: How to add a default error page using httpErrors

Example: How can I properly handle 404 in ASP.NET MVC?

Another great article: Demystifying ASP.NET MVC 5 Error Pages and Error Logging

This article explain in details how to properly setup 404 and 500: Custom error pages in ASP.NET MVC. Easy, right?

Community
  • 1
  • 1
Chris
  • 2,009
  • 1
  • 16
  • 25
  • Could you explain further please. I have attempted to use CustomErrors previously and couldnt get it working hence why i went with this approach – DaRoGa Mar 23 '16 at 14:02
  • I've edited my answer, you might want to google a bit, it's a common question. – Chris Mar 23 '16 at 14:12
1

Well I'm not sure about the error codes, but you shouldn't copy and paste code like that.

Make a function instead.

protected void Application_EndRequest()
{
    var response = new HttpResponseMessage((HttpStatusCode)Context.Response.StatusCode);

    if (!response.IsSuccessStatusCode)
    {
        switch (response.StatusCode)
        {
            case HttpStatusCode.BadRequest:
                ErrorAction("BadRequest");
                break;
            case HttpStatusCode.NotFound:
                ErrorAction("NotFound");
                break;
            case HttpStatusCode.InternalServerError:
                ErrorAction("InternalServerError");
                break;
            case HttpStatusCode.Forbidden:
                ErrorAction("Forbidden");
                break;
            default:
                ErrorAction("GenericError");
                break;
        }
    }
}

// Sends a request to the ErrorController
private void ErrorAction(string action)
{
    var rd = new RouteData();
    IController c = new ErrorController();

    Response.Clear();

    rd.Values["controller"] = "Error";
    rd.Values["action"] = action;

    c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));
}

That code suggests that you could eliminate the different ErrorController actions altogether, and just pass the StatusCode in the query-string to a single action method.

  • I agree the code is not refined and needs cleaning up to avoid the duplicated code, it was purely as i havent had chance to do that as yet and wanted to get thoughts. I will refactor how you suggested as i like that approach. However, do you believe this would be a suitable solution to do the job or is there a better / more refined method? – DaRoGa Mar 23 '16 at 14:05
  • As @Chris says in another answer, you don't need to write this code. MVC handles errors in the web.config. See http://stackoverflow.com/questions/717628/asp-net-mvc-404-error-handling –  Mar 23 '16 at 14:08
  • PS. Try to avoid writing code which needs cleaning up. :-) –  Mar 23 '16 at 14:10
  • I agree code shouldnt need cleaning up, however, i was at the point of struggling to get it working and that was the priority. I was going to clean it up before moving on thats for sure :) in regards to your other comment, like i mentioned on @Chris's answer, i could not get the custom errors working. I was trying this: ` ` – DaRoGa Mar 23 '16 at 14:12
  • Still not sure, but this issue will have been answered on stackoverflow already. –  Mar 23 '16 at 14:34
  • I have done some looking around trying lots of different things to try to get it to work to no avail. Most places seem to say it works for iis7+ so my conclusion is that i must be using a earlier version – DaRoGa Mar 23 '16 at 14:36