Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding [FromBody] attribute causes 404

I have an Action that takes a simple string parameter I send data to it using Ajax like this:

[HttpPost]
public async Task<IActionResult> Add(string data)

$.ajax({
        type: "POST",
        url: "/Items/Add",
        data: {
            data: item
        }
    })

This works fine, but after reading about model binding simple types in ASP.NET Core I learned you can use the [FromBody] attribute and prefix the value with '=' as well, so I rewrote it following examples like this:

[HttpPost]
public async Task<IActionResult> Add([FromBody] string data)

$.ajax({
        type: "POST",
        url: "/Items/Add",
        data: "=" + item,
        contentType: "text/plain"
    })

However after doing this my action is no longer hit and the ajax request comes back with a 404. This happens with or without setting the contentType: "text/plain", though I notice my Request payload is empty when not setting the contentType in the second example.

Update: I've gotten the [FromBody] attribute to work by rewriting the Ajax request like this:

$.ajax({
        type: "POST",
        url: "/Items/Add",
        data: JSON.stringify(item),
        contentType: "application/json"
    })

Adding application/json fixed the 404, but then the data was null. I had to update it to "'=" + item + "'" in order for the value to come through in the action, but then the "=" was still part of the data, so I don't get what the = prefix is all about in the documentation.

like image 309
Valuator Avatar asked Feb 15 '26 21:02

Valuator


1 Answers

I'm not sure about the text/plain content-type here, but your issue can be solved by doing 2 things:

  1. Change the [FromBody] to [FromForm] - [FromBody] only works for json data (I believe) which would explain why your your updated example worked... sort of. But because the model binder is now looking for JSON explicitly, you had to add the quotes and end up with the wrong answer.
  2. Change the content-type to application/x-www-form-urlencoded.

So it looks like this:

[HttpPost]
public async Task<IActionResult> Add([FromForm] string data)

$.ajax({
    type: "POST",
    url: "/Items/Add",
    data: "=" + item,
    contentType: "application/x-www-form-urlencoded"
})

Now the route will match, and the model binder will treat data as a form, easily defaulting =item to your action parameter.

Side note: I suspect you were getting a 415 media unsupported, not a 404.

like image 139
Balah Avatar answered Feb 18 '26 16:02

Balah



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!