fetch post method with razor page doesn't send body

Viewed 1750

I would like to trasnfer some data from the page to the page model with ajax (fetch api) post. I manage to get to "OnPostTest" handler, but I don't recive any data - variable "json" is null. Where is my problem? Is it on my ajax call or in the razor page model method? thanks

razor page- page model

public JsonResult OnPostTest(string json)
{
    return new JsonResult(json);
}

js

async function getData() {
    fetch('./test/Test',
        {
            method: "POST",
            body: JSON.stringify({
                json: 'yourValue'
            }),
            headers: {
                'X-CSRF-TOKEN': document.getElementsByName("__RequestVerificationToken")[0].value,
                'Content-Type': 'application/json',
                Accept: 'application/json',
            }
        })
        .then(function (res) { return res.json(); })
        .then(function (data) { alert((data)) })
}

razor page

<form method="post">
    <button type="button" onclick="getData(this)" value="1">send</button>
</form>

----Edit---- js

async function getData() {
    fetch('./test/Test',
        {
            method: "POST",
            body: JSON.stringify(
                {
                    name: "myname",
                    value: 1,
                    date:new Date()
                }
            ),
            headers: {
                'X-CSRF-TOKEN': document.getElementsByName("__RequestVerificationToken")[0].value,
                'Content-Type': 'application/json',
                'Accept': 'application/json',
            }
        })
        .then(function (res) { return res.json(); })
        .then(function (data) { alert((data)) })
}

razor page - page-model

public JsonResult OnPostTest([FromBody] ViewModel json)
        {
            return new JsonResult(json.Name);
        }

        public class ViewModel
        {
            public string Name { get; set; }
            public int Value { get; set; }
            public DateTime date { get; set; }
        }
1 Answers

The headers need to be changed. Because the bakend receive a string, so the body should be only a string.

fetch('[url]',
        {
            method: "POST",
            body: JSON.stringify(
                 'yourValue'
            ),

            headers: {
                RequestVerificationToken: document.getElementsByName("__RequestVerificationToken")[0].value,
                'Content-Type': 'application/json',
                Accept: 'application/json',
            }
        })
        .then(function (res) { return res.json(); })
        .then(function (data) { console.log(data) })

Add [FromBody] in page handler.

  public JsonResult OnPostTest([FromBody]string json)
    {
        return new JsonResult(json);
    }

Edit:

If passing the complex object {name:"myname",value:"5"}, you need to serilize the object with JSON.stringify().

      body: JSON.stringify(
             name:"myname",
             value:"5"
        ),

And the bakend should use a complex object to receive.

    public JsonResult OnPostTest([FromBody]ViewModel json)
    {
        return new JsonResult(json);
    }
     
    public class ViewModel
    {
        public string Name { get; set; }
        public int Value { get; set; }
    }
Related