0

I launch an asp.netcore mvc project with a controller accepting post with json object as parameter

then I used Insomnia rest client to test this action by posting json object to the action

however I get bad request error

when I do the post via webpage, it works fine

what is wrong with my test from the rest client

* Preparing request to http://localhost:51840/Books/Create
* Using libcurl/7.51.0-DEV OpenSSL/1.0.2j zlib/1.2.8 libssh2/1.6.1_DEV
* Enable automatic URL encoding
* Enable SSL validation
* Enable cookie sending with jar of 0 cookies
* Found bundle for host localhost: 0x1df804a67a0 [can pipeline]
* Re-using existing connection! (#6) with host localhost
* Connected to localhost (::1) port 51840 (#6)
> POST /Books/Create HTTP/1.1
> Host: localhost:51840
> User-Agent: insomnia/5.14.9
> Content-Type: application/json
> Accept: */*
> Content-Length: 32
| {
|   "Id" : 5,
|   "Name": "Book 3"
| }
* upload completely sent off: 32 out of 32 bytes
< HTTP/1.1 400 Bad Request
< Server: Kestrel
< X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcbWljcm9cRG9jdW1lbnRzXFZpc3VhbCBTdHVkaW8gMjAxN1xQcm9qZWN0c1xRdWlya3lCb29rTGlzdFxCb29rTGlzdFxCb29rTGlzdFxCb29rc1xDcmVhdGU=?=
< X-Powered-By: ASP.NET
< Date: Fri, 16 Mar 2018 08:03:48 GMT
< Content-Length: 0

* Curl_http_done: called premature == 0
* Connection #6 to host localhost left intact
1
  • 1
    Have you tried comparing (eg. use a debugging web proxy) the request from the browser with the one that's failing? Commented Mar 16, 2018 at 8:55

1 Answer 1

1

There's really not enough here to accurately answer your question, but one thing you said has me guessing a potential problem:

when I do the post via webpage, it works fine

A form submission via a web page is usually going to be encoded as x-www-form-urlencoded or multipart/form-data. ASP.NET Core will happily accept either encoding with no additional configuration. However, to accept JSON, the parameter you're binding to on your action method needs to be decorated with [FromBody]:

public IActionResult Foo([FromBody]Bar bar)

Once you do that, though, the action will no longer accept anything but JSON/XML/etc. If you try to post as x-www-form-urlencoded or multipart/form-data, it will fail.

So two things:

  1. If you need to accept something like JSON add the FromBody attribute to your action param.

  2. If you need to accept both something like JSON and a regular form post, you need two action methods. Yep, you read that right: two. One with FromBody and one without. Internally, you can factor out the actual code for the action method into a private or protected method on your controller and then have both actions use that, so at least you do not have to duplicate code.

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

2 Comments

Hi Chris thanks for the reply. Although that didn't work ... it got me thinking about the attributes ... turns out it is because of the [ValidateAntiForgeryToken] attribute. After I commented that out, it works. Thank you :)
"If you need to accept both something like JSON and a regular form post, you need two action methods". Yep, and those methods have to have different names, otherwise you'll get errors. So your API signature changes and client have to update their code. Gosh, another example of something that "just worked" in .NET Framework and stopped working in Core. :(

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.