HTTP 400 with JSON payload generated by ExceptionFilter not working

Hi,

I have a exception filter defined as :

public class JsonResponseExceptionFilter : FilterAttribute, IExceptionFilter
    {
        public void OnException(ExceptionContext filterContext)
        {
            var message = "Unexpected error";
            filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;

            var exceptionBase = filterContext.Exception.GetBaseException();
            
            if (exceptionBase is ApiExceptionBase || exceptionBase is ModelValidationException)
            {
                filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                message = exceptionBase.Message;
            }

            if (exceptionBase is UnauthorizedAccessException)
                filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
            
            filterContext.Result = new JsonResult
            {
                Data = new { Message = message },
                ContentEncoding = System.Text.Encoding.UTF8,
                ContentType = "application/json",
                JsonRequestBehavior = JsonRequestBehavior.AllowGet
            };

            filterContext.ExceptionHandled = true;
        }
    }

This works just fine on my ASP MVC 5 controller methods (debugging @ https://localhost:44301) 
Sending back a HTTP 400 with a JSON payload (response message) like this: 

{"Message":"some exception message"}

When the application is deployed to our test- or production environment this causes some problems. Via logging I can see that filterContext.Result is set correctly:

{"ContentEncoding":{"BodyName":"utf-8","EncodingName":"Unicode (UTF-8)","HeaderName":"utf-8","WebName":"utf-8",
"WindowsCodePage":1200,"IsBrowserDisplay":true,"IsBrowserSave":true,"IsMailNewsDisplay":true,"IsMailNewsSave":true,"IsSingleByte":false,
"EncoderFallback":{"DefaultString":"�","MaxCharCount":1},"DecoderFallback":{"DefaultString":"�","MaxCharCount":1},"IsReadOnly":true,"CodePage":65001},"ContentType":"application/json",
"Data":{"Message":"some exception message"},
"JsonRequestBehavior":0,"MaxJsonLength":null,"RecursionLimit":null}

but the client (browser) never receives this? it only gets the HTTP 400 without any JSON payload.
Also I noticed that the response header content-type changes to text/html (should be application/json; charset=utf-8).

So… my guess is that somewhere in the ASP request/response handling pipeline the response is "overridden" with some default value.
Can you provide me with any guidance to where this might be? Some setting I guess?

Thanks

Best regards 
Frederik

Hi,

To pass through exception messages, you can try setting

response.TrySkipIisCustomErrors = true;

For more information, please refer to the document:

http://stackoverflow.com/questions/4358339/how-to-prevent-iis7-for-handling-http-status-code-401

http://www.prideparrot.com/blog/archive/2012/5/exception_handling_in_asp_net_mvc

Leave a Reply