Search code examples
javascriptajaxasp.net-corefetchrazor-pages

fetch post method with razor page doesn't send body


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; }
        }

Solution

  • 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; }
        }