22

I post data using fetch like this in my client js scripts

    fetch('/myarea/mycontroller/myaction', {
        method: 'post',
        body: JSON.stringify({ name: namevalue, address: addressvalue })
    })
        .then(function (response) {
            if (response.status !== 200) {
                console.log('fetch returned not ok' + response.status);
            }

            response.json().then(function (data) {
                console.log('fetch returned ok');
                console.log(data);
            });
        })
        .catch(function (err) {
            console.log(`error: ${err}`);
        });
    }, false);

Then on my controller

    [HttpPost]      
    public async Task<IActionResult> MyAction(string name, string address)
    {
        // Error, name and address is null here, shouldn't be!
        // more code here ...
    }

My controller action is being called correctly, and I am able to debug inside it, but no data being passed. What could be wrong here? Thanks

3 Answers 3

18

The controller action is expecting query parameters (/myaction?name=myname&address=myaddress). That's the default. You're sending them in the body.

You can change the javascript to send them as query parameters. (see here: https://github.com/github/fetch/issues/256)

Or you can tell the controller action to take the values from the body:

[HttpPost]      
public async Task<IActionResult> MyAction([FromBody] Person person)
{
    var myName = person.Name;
}

public class Person
{
    public string Name {get; set; }

    public string Address {get; set; }
}
Sign up to request clarification or add additional context in comments.

5 Comments

I introduced [FromBody] and PersonModel in the controller, but it is not hitting my breakpoint anymore at the controller. It is not calling my controller. Why is it so?
The PersonModel works with query string but not with [FromBody]
It now works! I just set the fetch api headers like this headers: 'Content-Type': 'application/json;'
Adding [FromBody] didn't work, event with Content-Type set to application/json
@KVM Me neither. Did you manage to get it to work?
8

The [FromBody] attribute kicked in for me only after I defined the header that it is an "application/json" type:

fetch('api/Profile/Update', {
        method: 'post',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ description: "Some text here" })
    });

And this is how the controller action looks like:

    [HttpPost("[action]")]
    public async Task<IActionResult> Update([FromBody] ProfileUpdateModel profileUpdateModel)
    {
        //Do some stuff here...
        return  RedirectToAction("/", "HomeController");
    }

And the description property now receives the value from the request. Hope this gives final clarity to somebody tackling with the issue.

2 Comments

That URL you included in the fetch method: I assume Profile is the controller name and Update is the action method. I further assume its in the api folder. How do you configure this for it to know where the api folder is? Can you elaborate your answer?
@DeanP there is no api folder - just [Route("api/[controller]")] attribute which tells ASP how to recognise the route
3

Or if you had <form>...</form> you could use

fetch('/url', {
    method: 'POST',
    credentials: 'include',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: $('#editContactModal form').serialize() 
    // body like "id=1&clientid=3&name=me&phones=123&[email protected]"
})

without [FromBody] !!! (just with regular action method in controller)

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.