56

We're using OpenWeb js libraries on the frontend, and they have a need for the .NET middle tier to send them a specific HTTP header status code when certain types of errors occur. I tried to achieve that by doing this:

public ActionResult TestError(string id) // id = error code
{
    Request.Headers.Add("Status Code", id);
    Response.AddHeader("Status Code", id);
    var error = new Error();
    error.ErrorID = 123;
    error.Level = 2;
    error.Message = "You broke the Internet!";

    return Json(error, JsonRequestBehavior.AllowGet);
}

It kind of halfway worked. See screenshot: http status code http://zerogravpro.com/temp/pic.png

Notice I achieved the Status Code of 400 in the Response Header, but I really need the 400 in the Request Header. Instead, I get "200 OK". How can I achieve this?

My URL structure for making the call is simple: /Main/TestError/400

Hakan Fıstık
  • 16,800
  • 14
  • 110
  • 131
HerrimanCoder
  • 6,835
  • 24
  • 78
  • 158
  • Check out http://stackoverflow.com/questions/5072804/how-to-return-a-200-http-status-code-from-asp-net-mvc-3-controller – Matthew Aug 24 '12 at 15:36
  • I believe what he actually wants is setting the status code in the response status line (which is circled), rather than the request header. – Nick Jones Aug 24 '12 at 15:44
  • 1
    Requests don't have status codes, and even if you could do that, what would be the point of modifying the Request header information, you have already received it? – Matthew Aug 24 '12 at 15:44

3 Answers3

105

There is extended discussion at What is the proper way to send an HTTP 404 response from an ASP.NET MVC action?

What you want to do is set Response.StatusCode instead of adding a Header.

public ActionResult TestError(string id) // id = error code
{
    Response.StatusCode = 400; // Replace .AddHeader
    var error = new Error();  // Create class Error() w/ prop
    error.ErrorID = 123;
    error.Level = 2;
    error.Message = "You broke the Internet!";

    return Json(error, JsonRequestBehavior.AllowGet);
}
Community
  • 1
  • 1
Steve Czetty
  • 6,147
  • 9
  • 39
  • 48
  • 1
    @SweatCoder Returning content with StatusCode 400 is not a good idea. Mobile phone browsers (chrome, opera etc) doesn't receive the content, only the status code, breaking your client code expecting json. Therefore using HttpStatusCodeResult like Nick suggested is the correct solution. – Carl R Aug 22 '13 at 22:41
  • @CarlR It would be good to clarify what portion of the technology involved imposes that limitation. (MVC, the browser itself, the JavaScript libraries?) – jpmc26 Sep 09 '15 at 01:43
  • @jpmc26 The phone browser. – Carl R Sep 10 '15 at 08:20
  • 3
    @CarlR, modern [RESTful](https://en.wikipedia.org/wiki/RESTful) web services often return HTTP status codes with bodies explaining the error conditions. – Dan Lenski Aug 11 '17 at 17:01
61

If all you want to return is the error code, you could do the following:

public ActionResult TestError(string id) // id = error code 
{ 
      return new HttpStatusCodeResult(id, "You broke the Internet!");
}

Reference: MSDN article on Mvc.HttpStatusCodeResult.

Otherwise, if you want to return other information use

Response.StatusCode = id

instead of

Response.AddHeader("Status Code", id); 
Hakan Fıstık
  • 16,800
  • 14
  • 110
  • 131
Nick Jones
  • 6,413
  • 2
  • 18
  • 18
  • 9
    HttpStatusCodeResult has the added benefit of keeping the controller testable. Using Response introduces a dependency on an HttpContext. – Todd Menier Feb 19 '13 at 00:20
  • 3
    This doesn't work if you use the Action for jquery ajax call with dataType = json, because jquery expects json data back and an empty response above will error out. – Alexandra Dec 10 '13 at 03:10
  • 2
    The problem I've run into with `HttpStatusCodeResult` is that I have the actions called by AJAX returning `JsonResult`s, and `HttpStatusCodeResult` is not a `JsonResult`. You can just return an `ActionResult`, as a `JsonResult` is an `ActionResult`, but it makes the action signature misleading. – DCShannon May 15 '15 at 18:52
1

If you can't get your json result into your view, try to add this :

Response.TrySkipIisCustomErrors = true;

Before this :

Response.StatusCode = 400;

More details on this post : https://stackoverflow.com/a/37313866/9223103

Ludo.C
  • 55
  • 1
  • 6