

Why is the ASP.NET Core FromBody not working or returning null?
source link: https://www.roundthecode.com/dotnet/asp-net-core-web-api/why-asp-net-core-frombody-not-working-returning-null
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Why is the ASP.NET Core FromBody not working or returning null?
21st April 2021There can be issues when using the FromBody attribute in an ASP.NET Core Web API.
Where do we troubleshoot when the ASP.NET Core FromBody is not working?
We have made a JSON request to an API endpoint. However, what do we do when the parameter with FromBody is returning null? Or, we are being greeted with an 415 Unsupported Media Type error.
We are going to have a look at the FromBody and FromQuery attributes in ASP.NET Core.
As well as that, we will demonstrate how they behave in an ASP.NET Core Web API, and when to use them.
Setting up our request
For our demonstration, we are going to setup an ASP.NET Core Web API application using C#.
The first thing we will do is to create a model.
This model will consist of a customer record, which contains a first name and surname property.
The whole point of this model is that we will pass it in as a parameter inside a controller's action.
We can then see if the properties within the model are being bound successfully by the request.
// Customer.cs
public
class
Customer
{
public
string
Firstname {
get
;
set
; }
public
string
Surname {
get
;
set
; }
}
Setting up and testing endpoints using different methods
Next, we are going to set up a web controller.
This web controller will point to a route of /web
.
Within this controller, we are going to set up two actions.
The first action will be a HTTP GET method that will pass in our Customer
model as a parameter. We will return the Customer
model as a response to see if the request has managed to populate our Customer
model instance.
The other action will be a HTTP POST method that will work in the same way as our HTTP GET method. We pass in the Customer
model instance as a request, and return it as a response.
// WebController.cs
[Route(
"web"
)]
public
class
WebController
{
[HttpGet]
public
Customer Get(Customer customer)
{
return
customer;
}
[HttpPost]
public
Customer Post(Customer customer)
{
return
customer;
}
}
Now that we've done that, we are going to run some tests in Postman. We are running our ASP.NET Core Web API on https://localhost:7000
.
These are the tests we are running, and the responses returned.
URLRequest methodRequest bodyResponse codeResponsehttps://localhost:7000/web
GET (querystring)firstname=David&
200
surname=Grace{
"firstname": "David"
"surname": "Grace"
}https://localhost:7000/web
POST
(form-data)firstname=David
200
surname=Grace{
"firstname": "David"
"surname": "Grace"
}https://localhost:7000/web
POST
(x-www-form-url-encoded)firstname=David
200
surname=Grace{
"firstname": "David"
"surname": "Grace"
}https://localhost:7000/web
POST
(application/json){
200
"FirstName": "David"
"Surname": "Grace"
}{
"firstname": null,
"surname": null
}
The application/json request isn't working quite right?
The good news is that all our requests are returning a 200 response!
However, when we do a POST request using JSON, our properties within our Customer
model are not being set. They are still at their default value of null.
In-order to fix that, we can prepend the [FromBody]
attribute to our Customer
model instance in our parameter. We do that for the action that is performing our HTTP POST request.
// WebController.cs
public
class
WebController
{
...
[HttpPost]
public
Customer Post([FromBody] Customer customer)
{
return
customer;
}
}
Now, that's run our three HTTP POST tests again with the [FromBody]
attribute to see how they respond.
These are the tests we are running, and the responses returned.
URLRequest methodRequest bodyResponse codeResponsehttps://localhost:7000/web
POST
(form-data)firstname=david
415 (unsupported media type)
surname=gracehttps://localhost:7000/web
POST
(x-www-form-url-encoded)firstname=david
415(unsupported media type)
surname=gracehttps://localhost:7000/web
POST
(application/json){
200
"FirstName": "David"
"Surname": "Grace"
}{
"firstname": "David",
"surname": "Grace"
}
When we run a POST request using either form-data or x-www-form-url-encoded content type, it now throws a 415 unsupported media type error.
However, when we throw in a JSON request, not only does it return a 200 response, but it also populates our Customer
model type with the properties we sent in the request.
This is not how it's behaving?
When setting up a controller, there might be a case that the controller is not behaving in the same way when doing the above tests.
So why might this be the case?
Well, there is one reason why this is happening. There is an [ApiController]
attribute attached to the controller.
When an ASP.NET Core Web API is set up in Visual Studio, it creates a default WeatherForecast
controller. Within this controller, it contains the [ApiController]
attribute.
The [ApiController]
makes the controller behave in a different way when binding parameters from the request.
To demonstrate how this works, we are going to set up a new controller like the WebController
we set up earlier. However, this time, we are going to add the [ApiController]
attribute to the controller.
The other change we will make is pointing the route to /webapi
.
// WebApiController.cs
[ApiController]
[Route(
"webapi"
)]
public
class
WebApiController : Controller
{
[HttpGet]
public
Customer Get(Customer customer)
{
return
customer;
}
[HttpPost]
public
Customer Post(Customer customer)
{
return
customer;
}
}
Now, that's go ahead and run the same tests again to see what results we get.
URLRequest methodRequest bodyResponse codeResponsehttps://localhost:7000/webapi
GET (querystring)firstname=David&
415(unsupported media type)
surname=Gracehttps://localhost:7000/webapi
POST
(form-data)firstname=David
415(unsupported media type)
surname=Gracehttps://localhost:7000/webapi
POST
(x-www-form-url-encoded)firstname=David
415(unsupported media type)
surname=Gracehttps://localhost:7000/webapi
POST
(application/json){
200
"FirstName": "David"
"Surname": "Grace"
}{
"firstname": "David",
"surname": "Grace"
}
Fixing the HTTP GET request
Interestingly, the HTTP GET request using a querystring is throwing a 415 error, alongside the form-data and x-www-form-url-encoded content types in the HTTP POST request.
However, the application/json content type request is returning a 200 response, and is binding our request to our model.
When using any REST API, a HTTP POST request will typically expect an application/json content type as it's request. As a result, we are not going to try and attempt to fix the 415 errors with the other HTTP POST content types.
But how do we fix the HTTP GET request? Now we could make the request using the application/json type. But what if we want to use the querystring?
Well, for that, we can prepend the [FromQuery]
attribute to the parameter like so.
// WebApiController.cs
public
class
WebApiController : Controller
{
[HttpGet]
public
Customer Get([FromQuery] Customer customer)
{
return
customer;
}
...
}
Now that's rerun our HTTP GET request again and see what the result is.
URLRequest methodRequest bodyResponse codeResponsehttps://localhost:7000/webapi
GET (querystring)firstname=David&
200
surname=Grace{
"FirstName": "David",
"Surname": "Grace"
}
The [FromQuery]
attribute has now fixed our HTTP GET request.
If you wish to try it out for yourselves, you can download the source code.
In addition, check out our video where we implement these tests and demonstrate the results.
What to do if building an API controller?
When building an API controller, the best bet is to include the [ApiController]
attribute for the controller.
By creating a new controller in Visual Studio 2019, we can select the API controller template, and it will automatically add the [ApiController]
attribute for the controller.
This means that the [FromBody]
attribute will not be required on a POST request using JSON.
However, we need to remember to include the [FromQuery]
attribute if we are performing a HTTP GET request through the querystring.
Makes sense, but it does take some getting used to when getting started!
Download the Source Code
Please enter your address in the form below. We will then send you an email with the link to download the code.
Your email address will also be added to our newsletter list, which you can unsubscribe to at any time.
Recommend
-
55
在测试ASP.NET Core API 项目的时候,发现后台接口参数为类型对象,对于PostMan和Ajax的Post方法传Json数据都获取不到相应的值,后来在类型参数前面加了一个[FromBody
-
19
ASP.NET Core Pitfalls – Returning a Custom Service Provider from ConfigureServices In pre-3.1 versions of ASP.NET Core, you could return your own service provider (AutoFac,
-
8
Linq fails instead of returning null? advertisements I am trying to filter a list of items using the .Where method, and return the first item...
-
13
Returning to the office: An end to working from home after the pandemic delights or dismays employeesAllie Micka poses for a portrait in her D.C. home with her puppy, Ovi, via Zoom. (Carolyn Van Houten/The Washington Post)
-
12
ASP.NET Core Pitfalls – Null Models in Post Requests Sometimes, when AJAX posting to a controller, you may get a null model. Why? Let’s exclude the obvious – you didn’t send a null payload. The most typical reason is,...
-
7
There was an excellent question from Francis on my MySQL X DevAPI tutorial on how to work with NULL values:
-
10
-
6
Working Effortlessly with Java null in Scala Reading Time: 2 minutesWe would not repeat why null is a billion dollar mistake of Java. In our
-
66
swagger not working basesite null . Commerce Version 2205 Search Questions and Answers ...
-
4
.Net WebApi 中的 FromBody FromForm FromQuery FromHeader FromRoute ...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK