Complex type is getting null in a ApiController parameter
You are trying to send a complex object with GET
method. The reason this is failing is that GET
method can't have a body and all the values are being encoded into the URL. You can make this work by using [FromUri]
, but first you need to change your client side code:
$.ajax({
url: fullUrl,
type: 'GET',
dataType: 'json',
data: { Codigo: '_1', Descricao: 'TESTE', page: 1, pageSize: 10 },
success: function (result) {
alert(result.Data.length);
self.Parametros(result.Data);
}
});
This way [FromUri]
will be able to pick up your complex object properties directly from the URL if you change your action method like this:
public PagedDataModel<ParametroDTO> Get([FromUri]ParametroFiltro Filtro, int page, int pageSize)
Your previous approach would rather work with POST
method which can have a body (but you would still need to use JSON.stringify()
to format body as JSON).
Web API complex parameter properties are all null
This seems to be a common issue in regards to Asp.Net WebAPI.
Generally the cause of null objects is the deserialization of the json object into the C# object. Unfortunately, it is very difficult to debug - and hence find where your issue is.
I prefer just to send the full json as an object, and then deserialize manually. At least this way you get real errors instead of nulls.
If you change your method signature to accept an object, then use JsonConvert:
public HttpResponseMessage Post(Object model)
{
var jsonString = model.ToString();
PreferenceRequest result = JsonConvert.DeserializeObject<PreferenceRequest>(jsonString);
}
Post parameter is always null
Since you have only one parameter, you could try decorating it with the [FromBody]
attribute, or change the method to accept a DTO with value as a property, as I suggested here: MVC4 RC WebApi parameter binding
UPDATE: The official ASP.NET site was updated today with an excellent explanation: https://learn.microsoft.com/en-us/aspnet/web-api/overview/advanced/sending-html-form-data-part-1
In a nutshell, when sending a single simple type in the body, send just the value prefixed with an equal sign (=), e.g. body:
=test
Web API Complex type property always null
Try without JSON.stringify
var data = {"name":"test"};
$.ajax({
type: "POST",
url: "api/book/create",
data: data,
dataType: "json",
success: function (result) {
alert(result);
}
});
Web Api - IEnumerable with complex type as param is null
If you want send to only one mail your host method param and json data are wrong
Post Method
[HttpPost]
[Route("message")]
public IHttpActionResult Post(Email email)
{
return Ok("message sent");
}
Json Data
{
"Body":"body",
"From":"from",
"To":"to",
"Template":"template"
}
Or If you want to send more email only your json data is wrong
Json data for more email
[
{"Body":"body","From":"from","To":"to","Template":"template"},
{"Body":"body1","From":"from1","To":"to1","Template":"template1"},
{"Body":"body2","From":"from2","To":"to2","Template":"template2"}
]
Web Api Parameter always null
$.ajax({
url: '/api/search',
type: 'POST',
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
data: '=' + encodeURIComponent(request.term),
success: function (data) {
response(data.d);
},
error: function (result) {
alert('Error');
}
});
Basically you can have only one parameter of scalar type which is decorated with the [FromBody]
attribute and your request needs to use application/x-www-form-urlencoded
and the POST payload should look like this:
=somevalue
Notice that contrary to standard protocols the parameter name is missing. You are sending only the value.
You can read more about how model binding in the Web Api works in this article
.
But of course this hacking around is a sick thing. You should use a view model:
public class MyViewModel
{
public string Value { get; set; }
}
and then get rid of the [FromBody]
attribute:
public IEnumerable<string> Post(MyViewModel model)
{
return new string[] { "value1", "value2", model.Value };
}
and then use a JSON request:
$.ajax({
url: '/api/search',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ value: request.term }),
success: function (data) {
response(data.d);
},
error: function (result) {
alert('Error');
}
});
How do I make my API action accept null complex types?
What I think you are looking for is how to define "Routing Rules"
WebApi 2.0 let's use an attribute called Route
to define different "Resource URLs" with some rules(constraints) like length, format and default values
For example:
public class SomeController : ApiController{
//where author is a letter(a-Z) with a minimum of 5 character and 10 max.
[Route("html/{id}/{newAuthor:alpha:length(5,10)}/age:int?")]
public Book Get(int id, string newAuthor , int age){
return new Book() { Title = "SQL Server 2012 id= " + id, Author = "Adrian & " + newAuthor };
}
Where the parameter age is of type integer
and optional.
Or like this using a default value:
[Route("html/{id}/{newAuthor:alpha:length(5,10)}/age:int=33")]
public Book Get(int id, string newAuthor , int age){
return new Book() { Title = "SQL Server 2012 id= " + id, Author = "Adrian & " + newAuthor };
}
...
Or being able to customize your routings based on your needs like :
[Route("url1/{id}")]
public Book Get(int id){
return new Book() { Title = "SQL Server 2012 id= " + id, Author = "Adrian " };
}
[Route("url1/{id}/{author}")]
public Book Get(int id, string author){
return new Book() { Title = "SQL Server 2012 id= " + id, Author = "Adrian & " + author };
}
...
In the first version of the WebApi this had to be done in the WebApiConfig
class however the options are not the same, I think the only real option on that version was the use of regular expressions.
Going back to Web.Api 20 you also can define your own constraints to handle your own complex types by inheriting from IHttpRouteConstraint
There is additional information regarding the scenario you described on the WEB.Api documentation site, it is possible that you may need to implement a TypeConverter
.
http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api
FromBody string parameter is giving null
By declaring the jsonString parameter with [FromBody]
you tell ASP.NET Core to use the input formatter to bind the provided JSON (or XML) to a model. So your test should work, if you provide a simple model class
public class MyModel
{
public string Key {get; set;}
}
[Route("Edit/Test")]
[HttpPost]
public void Test(int id, [FromBody] MyModel model)
{
... model.Key....
}
and a sent JSON like
{
key: "value"
}
Of course you can skip the model binding and retrieve the provided data directly by accessing HttpContext.Request
in the controller. The HttpContext.Request.Body
property gives you the content stream or you can access the form data via HttpContext.Request.Forms
.
I personally prefer the model binding because of the type safety.
Related Topics
How to Pass a Single Object[] to a Params Object[]
The Name "Xyz" Does Not Exist in the Namespace "Clr-Namespace:Abc"
If Int32 Is Just an Alias for Int, How Can the Int32 Class Use an Int
Create PDF in Memory Instead of Physical File
How Does Comparison Operator Works with Null Int
Using Variables Inside Strings
Does Lock() Guarantee Acquired in Order Requested
Unit Testing and Checking Private Variable Value
Regex: C# Extract Text Within Double Quotes
Enumerate Windows Like Alt-Tab Does
Limiting Double to 3 Decimal Places
Multi-Select Dropdown List in ASP.NET
How to Do .Net Binary Serialization of an Object When You Don't Have the Source Code of the Class