Return Mvc.JsonResult plus set Response.StatusCode

21,925

Solution 1

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.

Solution 2

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.

Solution 3

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

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

Share:
21,925
Brent
Author by

Brent

an amateur programmer with interest in javascript (and jQuery), SQL and ASP.NET

Updated on July 09, 2022

Comments

  • Brent
    Brent almost 2 years

    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

  • Henry Wilson
    Henry Wilson over 9 years
    Thanks for this, invaluable!
  • Shawn de Wet
    Shawn de Wet over 9 years
    @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!
  • Jacob McKay
    Jacob McKay about 8 years
    I had to add <httpErrors errorMode="Custom" existingResponse="Auto"> as well because existingResponse="Replace" would ignore the TrySkipIisCustomErrors!
  • Pogrindis
    Pogrindis over 5 years
    Like so many people, I've had weird IIS issues before, but I will be honest, this one takes the biscuit.
  • Pogrindis
    Pogrindis over 5 years
    Please merge this into the Mvc API .. Dear god this is what most would consider essential.
  • Pogrindis
    Pogrindis over 5 years
    I would just extend to include <T> IE : public class JsonResultWithHttpStatusCode<T>
  • Suncat2000
    Suncat2000 over 2 years
    @Pogrindis What's T?