Mvc: ASP.NET Core Web API - POST JSON, no Data Passed

Created on 18 Jan 2018  路  10Comments  路  Source: aspnet/Mvc

_From @jkergosi on January 17, 2018 23:46_

I have an existing web api call in .NET 4.7, when brought to .NET Core 2, doesn't work. I'd updated my code to be 2.0 compliant, but when I POST, the JObject parameter is not populated.

```c#
[Produces("application/json")]
[Route("api")]
public class MyController : Controller
{
[HttpPost("Create")]
public async Task Create([FromForm] JObject data)
{
if (data == null)
return new HttpResponseMessage { StatusCode = HttpStatusCode.BadRequest, ReasonPhrase = "POST body is null" };

        try
        {
            await db.CreateItemAsync(data);
            return new HttpResponseMessage { StatusCode = HttpStatusCode.OK, ReasonPhrase = "Saved" };
        }
        catch (Exception ex)
        {
            return new HttpResponseMessage { StatusCode = HttpStatusCode.InternalServerError, ReasonPhrase = $"Document could not be created: {ex.InnerException}" };
        }
    }

}

```javascript
The JQuery call is:
function SaveDocument() {

    var myData = JSON.stringify({ "userName": "bob", "password": "123" });

    $.ajax({
        url: url,
        type: "POST",
        contentType: "application/json",
        dataType: "json",
        data: myData,

        success: function (result) {
            console.log(result);
        },

        error: function (xhr, resp, text) {
            console.log(xhr, resp, text);
        }
    });
}

The Create method is called, but the JObject parameter is empty:

results

I've also tried dynamic instead of JObject, but no dice.

Any suggestions? Thanks!

_Copied from original issue: aspnet/Home#2793_

Most helpful comment

Thanks to you guys, it's working now.

[FromBody] with the JObject did the job. In my attempts at troubleshooting, I accidentally hosed my incoming JSON, so its incorrect format prevented the JObject from being bound, leaving a perfectly good controller in the wind.

Here's the working code:

```c#
[HttpPost("Create")]
public async Task Create([FromBody] JObject data)
{
if (data == null)
return new HttpResponseMessage { StatusCode = HttpStatusCode.BadRequest, ReasonPhrase = "POST body is null" };

        try
        {
            await Db.CreateItemAsync(data);
            return new HttpResponseMessage { StatusCode = HttpStatusCode.OK, ReasonPhrase = "Saved" };
        }
        catch (Exception ex)
        {
            return new HttpResponseMessage { StatusCode = HttpStatusCode.InternalServerError, ReasonPhrase = $"Document could not be created: {ex.InnerException}" };
        }
    }
```javascript
function SaveDocument() {

    var myData = JSON.stringify({ "userName": "bob", "password": "123" });

    $.ajax({
        url: url,
        type: "POST",
        contentType: "application/json",
        dataType: "json",
        data: myData,

        success: function (result) {
            console.log(result);
        },

        error: function (xhr, resp, text) {
            console.log(xhr, resp, text);
        }
    });
}

All 10 comments

_From @Tratcher on January 18, 2018 0:29_

Shouldn't [FromForm] be [FromBody]?

_From @jkergosi on January 18, 2018 0:54_

Normally, yes, but other posts recommended that it is needed. I've tried [FromBody] before and it unfortunately doesn't work.

There's no model binder for JObject, right?

I think you need to either write and add a model binder (provider) for JObject or change the signature to [FromBody] string json and manually parse it to a JObject using JObject.Parse(json).

The question is; should there be a built-in model binder for JObject (and family)?

@khellang Thank Kristian, though I'd tried passing a string as well, to no avail, using FromBody as well as FromForm. I know it's probably an easy fix, but I've been banging my head against this one! :)

Thanks everyone for replying.

@Tratcher I'm taking a look at your code now, and though I see the controller, I don't see a reference to call it. Was hoping for a client-side call. Thoughts?

Hi @jkergosi. You should definitely use FromBody instead of FromForm in your scenario.
Using JObject, as @Tratcher has already pointed out, should work. It looks like you have some misconfiguration somewhere.

Have you tried to not stringify the data from client before passing to JQuery?
Also, can you share with us the actual request body (Dev tools in browser will be handy here)?

Thanks to you guys, it's working now.

[FromBody] with the JObject did the job. In my attempts at troubleshooting, I accidentally hosed my incoming JSON, so its incorrect format prevented the JObject from being bound, leaving a perfectly good controller in the wind.

Here's the working code:

```c#
[HttpPost("Create")]
public async Task Create([FromBody] JObject data)
{
if (data == null)
return new HttpResponseMessage { StatusCode = HttpStatusCode.BadRequest, ReasonPhrase = "POST body is null" };

        try
        {
            await Db.CreateItemAsync(data);
            return new HttpResponseMessage { StatusCode = HttpStatusCode.OK, ReasonPhrase = "Saved" };
        }
        catch (Exception ex)
        {
            return new HttpResponseMessage { StatusCode = HttpStatusCode.InternalServerError, ReasonPhrase = $"Document could not be created: {ex.InnerException}" };
        }
    }
```javascript
function SaveDocument() {

    var myData = JSON.stringify({ "userName": "bob", "password": "123" });

    $.ajax({
        url: url,
        type: "POST",
        contentType: "application/json",
        dataType: "json",
        data: myData,

        success: function (result) {
            console.log(result);
        },

        error: function (xhr, resp, text) {
            console.log(xhr, resp, text);
        }
    });
}

Thanks everyone for your help!

Thanks a Lot. You saved my day too.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MariovanZeist picture MariovanZeist  路  4Comments

michaelbowman1024 picture michaelbowman1024  路  3Comments

karthicksundararajan picture karthicksundararajan  路  4Comments

DamianEdwards picture DamianEdwards  路  3Comments

workmonitored picture workmonitored  路  3Comments