IIS 8.5 overriding custom JSON error response, instead returns the default 500 error response page. How can I get IIS 8.5 to return my custom error?

All we need is an easy explanation of the problem, so here it is.

I’ve come across an annoying issue, which I think is being caused by IIS 8.5. With a web app that I’m creating, I have created a custom JSON HttpStatusResult class (which was an idea from this stackoverflow post), which enables me to return JSON along side a 500, 400 or other types of HTTP response status codes. Here is that code:

public class JsonHttpStatusResult : JsonResult
{
    private readonly HttpStatusCode _httpStatus;

    public JsonHttpStatusResult(object data, HttpStatusCode httpStatus)
    {
        Data = data;
        _httpStatus = httpStatus;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        context.RequestContext.HttpContext.Response.StatusCode = (int)_httpStatus;
        JsonRequestBehavior = JsonRequestBehavior.AllowGet;
        base.ExecuteResult(context);
    }
}

While testing locally, using IISExpress, this works as I’d expect – if I return a 500 Http status code along with some JSON, the response contains just the JSON. However, when I publish the site to the IIS 8.5 web server that we have (We do not yet have any running IIS 10, unfortunately – I don’t think that would make a difference anyway?) it instead returns the default 500 error response page, and not the JSON:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>500 - Internal server error.</title>
<style type="text/css">
<!--
body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}
fieldset{padding:0 15px 10px 15px;} 
h1{font-size:2.4em;margin:0;color:#FFF;}
h2{font-size:1.7em;margin:0;color:#CC0000;} 
h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;} 
#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS", Verdana, sans-serif;color:#FFF;
background-color:#555555;}
#content{margin:0 0 0 2%;position:relative;}
.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}
-->
</style>
</head>
<body>
<div id="header"><h1>Server Error</h1></div>
<div id="content">
 <div class="content-container"><fieldset>
  <h2>500 - Internal server error.</h2>
  <h3>There is a problem with the resource you are looking for, and it cannot be displayed.</h3>
 </fieldset></div>
</div>
</body>
</html>

So this is what I’m stuck at – how do I get IIS to return my custom 500 JSON error result, instead of this default 500 page? I’ve taken a look around and seen some posts mentioning that these are two important lines of code that are needed:

HttpContext.Response.Clear();
HttpContext.Response.TrySkipIisCustomErrors = true;

However, I don’t know how to set these when sending my custom error response, as once I return a JSON error response, like in this example:

return new JsonHttpStatusResult(new
{
    ResponseMessage = ex.Message
},
HttpStatusCode.InternalServerError);

I’m not then able to set the response as no more code runs once the return is called? Is there some kind of way I can hook into the response once my custom Json result class has created the response, I saw something kind of like that with this post, but unfortunately it doesn’t seem to explain how I’m supposed to use this?

It’s worth mentioning, that the reason I’m trying to return JSON error responses is because these actions are being called by Ajax from the front end, and then these errors are handled/displayed by the javascript on the frontend, which I why I’m trying to pass back more than just a "500 internal server error" message.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

Ok then, found a solution to my problem, all I had to do in my case was add this to the web.config within the system.webServer element:

<httpErrors existingResponse="PassThrough"/>

Didn’t need to change any other settings, or modify the response in the end. It seems that this setting causes IIS to pass the existing response through on an error.

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply