Search code examples
c#jsonasp.net-corehttp-post

ASP Core 2 empty POST request


I've got a simple HTTP POST request, which I send to an ASP Core 2 application running in localhost with Kestrel. The received data is always null unless I use PostAsJsonAsync from another C# app.

The json I'm sending has this form:

{
  "_isValid": true,
  "_username": "test",
  "_guid": "f3f574eb-5710-43c5-a4ff-0b75866a72a7",
  "_dt": "2018-02-11T15:53:44.6161198Z",
  "_ms": "IsSelected"
  [...]
}

The ASP controller has this form:

// POST: api/NativeClient
[HttpPost]
public async Task<IActionResult> Post([FromBody]string value)
{
   [...]

1. Case: sending with PostAsJsonAsync from another C# app

In one case I'm successfully sending the request via another separate C# application which uses PostAsJsonAsync like this:

HttpClient client = new HttpClient();
client.BaseAddress = new System.Uri("http://localhost:51022/");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

var response = await client.PostAsJsonAsync("/api/NativeClient/", json);

The controller receives the call and populates value successfully.

2. Case: sending with an external REST client like Postman

In another case I try to send the request via another REST client, such as Postman or Visual Studio Code through REST client extension:

POST http://localhost:51022/api/NativeClient/ HTTP/1.1
content-type: application/json; charset=utf-8

{
  "_isValid": true,
  "_username": "gnappo",
  "_guid": "f3f574eb-5710-43c5-a4ff-0b75866a72a7",
  "_dt": "2018-02-11T15:53:44.6161198Z",
  "_ms": "IsSelected"
  [...]
}

Here the request is received by the controller, but the string value is always null.

I've tried removing the [FromBody] tag, checking the request header, checking the json string in the body (which is exactly the same), and other things mentioned in the references below, but nothing works.

What am I missing?


Other tests tried/references

Value are always null when doing HTTP Post requests

Asp.net Core 2 API POST Objects are NULL?

Model binding JSON POSTs in ASP.NET Core


Solution

  • The POST request needs to declare that the sent data is text/plain. Using the example with HttpClient:

    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain"));
    

    This way, your API will be able to receive your JSON as a string content.

    If instead you want to receive your content deserialized into the original model object, you need to add this header into your request:

    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    

    and change your controller to:

    // POST: api/NativeClient
    [HttpPost]
    public async Task<IActionResult> Post([FromBody]yourClass class)
    {
       [...]
    

    Send JSON object to your API:

    var Content = new StringContent(json, Encoding.UTF8, "application/json");
    var response = await client.PostAsync("/api/NativeClient/", Content);
    

    PostAsJsonAsync takes a C# Object as an input; it serializes it as a JSON string before sending it. Instead, PostAsync can take a JSON string to send.

    see this Q&A httpclient-not-supporting-postasjsonasync-method-c-sharp

    see this links for more info:

    PostAsJsonAsync in C#

    PostAsync