9

I've got a weird problem with returning a 400 status code with json on error.

In my controller, I've got something like:

if(!ModelState.IsValid)
{
    string[] errors = ModelState.Values
                            .SelectMany(x => x.Errors)
                            .Select(x => x.ErrorMessage).ToArray<string>();

    Response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
    return Json(new { success = false, errors = errors }, JsonRequestBehavior.DenyGet);
}

This works fine on my development machine. I can get the errors in the ajax error method. But when I deploy to the server, the server doesn't return the JSON anymore. I always get responseText instead of reponseJSON. If I remove the Response.StatusCode it works fine.

This leads me to believe that the function 'returns' when I set the Response object's StatusCode property. Has this happened to anyone else? Anyone know the solution?

1
  • make it JsonRequestBehavior.AllowGet Commented May 19, 2016 at 4:09

2 Answers 2

23

I finally figured out what the problem is. Posting this here as an answer for anyone else who may be pulling their hair out over this.

Set the following:

Response.TrySkipIisCustomErrors = true;

Make sure that this is set before you set the status code. I also figured out why it was working on my local machine and not on the test/uat servers. In my web.config, the CustomErrors was set to Off whereas on the servers it was set to On.

Seems like the server 'returns' as soon as it sees a BadRequest status code being written to the Response.

Sign up to request clarification or add additional context in comments.

3 Comments

Great! BTW you don't need it under IIS 10, but still need it under IIS7. At least this is my experience (inconsistency is pain in a ass, moving between development and production causes unexpected challenges)
Thanks for posting the answer. I was having the same problem when publishing in AWS Elasticbeanstalk servers.
Thank you so much for the answer and explanation on why it didn't work. It worked for me.
1

Well, even though you are explicitly casting, Response.StatusCode is a child element of Response.

In most cases, the easiest way I find and following "best practices" for creating WebAPI's:

First, your method signature would change from:

public JsonResult Action() { ... }

to

public IHttpActionResult Action { ... }

then instead of returning Json() you would use the following:

return Content(HttpStatusCode.BadRequest, new {success = false, errors = errors }, Configuration.Formatters.JsonFormatter);

where the final variable, Configuration.Formatters.JsonFormatter is optional--remember, Json is the default return type (or ASP.NET allows for content negotiation and will follow what the client requests).

Hope that helps.

2 Comments

Hey, thanks. Unfortunately, I'd already tried that and it hadn't worked. I've added as an answer, what finally worked. Although I'd love to know the source of 'best practices' for the things you've mentioned.
@JeevanJose interesting, what issues were you having using the above code? Same exact bug? As far as best practices go, I'm going based on what's recommended when crafting API's by most .NET experts (Shawn Wildermuth on Pluralsight has a few great ones in particular: app.pluralsight.com/library/courses/web-api-design/… app.pluralsight.com/library/courses/… and finally app.pluralsight.com/library/courses/… ).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.