Search code examples
c#asp.net-coreasp.net-core-webapihttp-response-codes

Http 429 is not returnable in status code from C# ASP.NET Core Web API


[Route("{route}")]
[HttpPost]
public async Task<System.Net.Http.HttpResponseMessage> Post([FromBody] dynamic data)
{
    var test = new HttpResponseMessage(HttpStatusCode.TooManyRequests);
    return test;
}

Implementing an ASP.NET Core Web API controller. The intention is to return HTTP 429.

However, the 429 is returned in the response body but the actual response is HTTP 200

Example response from Postman below

{
    "Version": "1.1",
    "Content": {
        "Headers": []
    },
    "StatusCode": 429,
    "ReasonPhrase": "Too Many Requests",
    "Headers": [],
    "TrailingHeaders": [],
    "RequestMessage": null,
    "IsSuccessStatusCode": false
}

enter image description here

Any ideas how to fix this please?

I want the response in Postman to have a HTTP 429 status code.

Ideally, my expectation is that both response body and response header should be containing HTTP 429 (here, the response payload status is 429 but the response header contains 200)


Solution

  • This is because you are creating your own HttpResponseMessage, which is totally wrong - it's not how ASP.NET HTTP pipeline works. It does not pick just randomly created HTTP messages. That's why you don't see the results you expect.

    The HTTP response that will be returned can be referenced through HttpContext.Response (HttpContext is property that is inherited from ControllerBase), and you can set its property StatusCode - this will take effect you expect.

    The easiest solution is:

    HttpContext.Response.StatusCode = (int)HttpStatusCode.TooManyRequests;
    

    Returning additional data

    To return additional data, you can set the body of the HTTP response directly on HttpContext.Response, but that wouldn't look well. Instead, you should set return type of the endpoint method to IActionResult and then you can leverage ObjectResult class, as follows:

    [HttpPost]
    public async Task<IActionResult> Post([FromBody] dynamic data)
    {
        HttpContext.Response.StatusCode = (int)HttpStatusCode.TooManyRequests;
        return new ObjectResult(new { AnyData = "any data" });
    }