44

Project: ASP MVC 4 running under .net 4.0 framework:

When running an application under VS 2010 express (or deployed and running under IIS 7.5 on my local machine) the following (pseudocode) result from an action works as expected

[HttpPost]
public ActionResult PostWord(Model model)
{
   ....
   Response.StatusCode = 400;
   Return new JsonResult { data = new {fieldName = "Word", error = "Not really a word!" } };

(and I have assigned ContentType and ContentEncoding properties of the JsonResult object, with no difference in behaviour)

When the deployable is moved onto a web host (using IIS 7), firebug is telling me that the response is as expected (400) but there is no JSON in the response (ie there is no text of any kind). If I remove the line

Response.StatusCode = 400;

from the action, the JSON is perfectly formed in the response, but of course the response status code is 200 (OK), which interferes with the consuming javascript and appropriate function call.

Any thoughts on what might be going on and how to fix this? Thank you

6
  • Why do you want to return 400? Isn't this just an error page with a friendly error message Commented Jun 19, 2013 at 4:48
  • stackoverflow.com/questions/6123425/… maybe I should do things differently, but JSON is returned regardless - the response code gives the postback function information in order to know what to do with the JSON. 200 to me means 'database updated as requested'. Commented Jun 19, 2013 at 4:54
  • I would check the error field in the JSON instead of the http status code Commented Jun 19, 2013 at 4:57
  • IIS7 hides detailed error messages by default, so you don't get any content when an error is returned. Try changing the iss7 setup to return detailed error messages and see if that works Commented Jun 19, 2013 at 8:24
  • 27
    It could be an issue with IIS Custom errors. Maybe try setting Response.TrySkipIisCustomErrors = true; link Commented Jun 27, 2013 at 22:52

3 Answers 3

61

I had this exact same problem; in order to make sure that the correct answer is not buried in the comments (as it was for me), I want to reiterate @Sprockincat's comment:

For me at least, it was indeed an issue with IIS Custom errors, and can be solved with:

Response.TrySkipIisCustomErrors = true;

@Sprockincat - you should get credit for this. I'm just making it more visible because it's such a subtle fix to a problem that is quite difficult to diagnose.

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

3 Comments

@Robert if I could upvote this answer every day for the next year I would!! Thanks for this! This frikkin' problem had me digging for the past 12 hours! Thank you thank you thank you thank you. And thanks to Brent for the opening post!
I had to add <httpErrors errorMode="Custom" existingResponse="Auto"> as well because existingResponse="Replace" would ignore the TrySkipIisCustomErrors!
Like so many people, I've had weird IIS issues before, but I will be honest, this one takes the biscuit.
4

I've created a subclass of JsonResult that allows you to specify the HttpStatusCode.

public class JsonResultWithHttpStatusCode : JsonResult
{

    private int _statusCode;
    private string _statusDescription;

    public JsonResultWithHttpStatusCode(object data, HttpStatusCode status) 
    {
        var code = Convert.ToInt32(status);
        var description = HttpWorkerRequest.GetStatusDescription(code);
        Init(data, code, description);
    }

    public JsonResultWithHttpStatusCode(object data, int code, string description)
    {
        Init(data, code, description);
    }

    private void Init(object data, int code, string description)
    {
        Data = data;
        _statusCode = code;
        _statusDescription = description;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        context.HttpContext.Response.StatusCode = _statusCode;
        context.HttpContext.Response.StatusDescription = _statusDescription;
        base.ExecuteResult(context);
    }
}

Then you can return this as your result and the status code will get set on the response. You can also test the status code on the result in your tests.

3 Comments

Please merge this into the Mvc API .. Dear god this is what most would consider essential.
I would just extend to include <T> IE : public class JsonResultWithHttpStatusCode<T>
@Pogrindis What's T?
0

For anyone looking for this - in ASP.NET Core you can set the StatusCode property of JsonResult.

https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.jsonresult.statuscode

1 Comment

That will still return 200 whether you set JsonResult's StatusCode to 500 or something else.

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.