3

There is a simple ajax POST request that must stringify a simple class and pass it in the body of POST request, but the Person parameter on the server-side has empty(default) values

// javascript
var person = { "FirstName": "Andrew", "LastName": "Lock", "Age": "31" };
$.ajax({
    type: "POST",
    url: "/UpdatePostBody?handler=Abc",
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    data: JSON.stringify(person),
    headers: {
        RequestVerificationToken:
            $('input:hidden[name="__RequestVerificationToken"]').val()
    },
})
    .done(function (result) {
        console.log(result);
});
// C# code
public IActionResult OnPostAbc(Person person)
{
    return new JsonResult("my result");
}

enter image description here

On the server-side, there is a simple ASP.NET Core Razor page with a method that gets hit and returns the result but the person param members have no values.

3 Answers 3

10

Your Pesron data is null is because your Age in class Person is int type.And your person in { "FirstName": "Andrew", "LastName": "Lock", "Age": "31" } is string type,So you cannot get it.Also,as you pass json data from ajax to handler,you need to add [FromBody] in handler.Here is a demo:

cshtml:

<button onclick="postdata()">Abc</button>
function postdata() {
        //change Age type to int
        var person = { "FirstName": "Andrew", "LastName": "Lock", "Age": 31 };
        $.ajax({
            type: "POST",
            url: "/UpdatePostBody?handler=Abc",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            data: JSON.stringify(person),
            headers: {
                RequestVerificationToken:
                    $('input:hidden[name="__RequestVerificationToken"]').val()
            },
        })
            .done(function (result) {
                console.log(result);
            });
    }

cshtml.cs:

public IActionResult OnPostAbc([FromBody]Person person)
        {
            return new JsonResult("my result");
        }

result: enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

[FromBody] of course was used, the real problem was the "31" string used instead of an int value, just haven't observed the typo
2

As you have identified, JSON is sent as part of the request body. You could (as you have done in your own answer) read the input stream and deserialize it manually, but there is a much simpler way using the [FromBody] attribute on the handler parameter:

public IActionResult OnPostAbc([FromBody] Person person)
{
    return new JsonResult($"my result: {person.FirstName} {person.LastName}");
}

However, this only works in 3.1 with the default serializer (System.Text.Json) if you remove the quotes from numbers in your person object:

var person = { "FirstName": "Andrew", "LastName": "Lock", "Age": 31 };

Or if you add your own type converter.

The previous serializer, JSON.Net, is happy with either version. And quoted numbers are supported in ASP.NET Core 5.

2 Comments

Thanks but this method does not work :)(I have tried it), maybe because of Razor pages?
I've updated my answer to include a note about quoted numbers
1

Solved by reading the data from POST body

public async Task<IActionResult> OnPostAbc()
{
    var buffer = new byte[1024];
    using (var ms = new MemoryStream())
    {
        var read = 0;
        while ((read = await Request.Body.ReadAsync(buffer, 0, buffer.Length)) != 0)
        {
            ms.Write(buffer, 0, read);
        }
        ms.Seek(0, SeekOrigin.Begin);
        var person = 
            JsonConvert.DeserializeObject<Person>(Encoding.UTF8.GetString(ms.GetBuffer()));
        return new JsonResult($"my result: {person.FirstName} {person.LastName}");
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.