First of all, I'm very green with anything web, so please bear with me :-)
I'm trying to wrap my head around the various aspects of web applications, and at the same time learning WebAPI.
I'm working with KendoUI on the front end, and following some of their "default" way of doing things (that means using their DataSource object), I request data from a WebAPI controller with a GET.
When looking at the request with Fiddler, I can see in the WebForms tab that Fiddler knows how to "decipher" the querystring:
filter[logic]
and
filter[filters][0][field]
FolderID
filter[filters][0][operator]
eq
filter[filters][0][value]
2
I've been trying to understand how the default model binder in WebAPI would let me serialize (is that the proper word ?) the querystring to Action parameters, but I've failed miserably so far !
Can anyone offer a word or two of advice how to massage this querystring into proper parameters ?
It's using the model binder, and you are probably using characters that are disallowed.
There are properties you can look at to look at the input source (to see what the fields turned into) but I am still on preview 6, so I don't know the specifics, sorry. It has to do with request input parameters.
If the default model binder is not working, then you have to make your own model binder by using action filters.
You would have to read the response yourself, and add the the request parameters how you want your input args named.
As a further test, I changed the request from a GET to a POST (both on the server side and the client side), and now I can get the Model Binder to work when using the following classes:
public class GridFilter
{
public string Operator { get; set; }
public string Field { get; set; }
public string Value { get; set; }
}
public class GridFilters
{
public List<GridFilter> Filters { get; set; }
public string Logic { get; set; }
}
//Action signature:
[System.Web.Mvc.HttpPost]
public IQueryable<Building> Get(WebApi1.Models.GridFilters filter = null)
{...}
Correct me if I'm wrong, but the difference is that the POST parameters are passed as part of the request body, while the GET parameters are passed in the querystring (It seems to be so from what I see in Fiddler).
Does it mean that the WebAPI default model binder will not work for complex types in querystrings ?
I'd like to understand the difference in WebAPI's binder behavior.
webapi now uses the mvc model binder, so what works with that will work with webapi.
When you say "difference" I guess you mean qs to post.
QS does not support complex types that well. I am pretty sure there is a different model binder for the QS than the body.
For instance the body only allows a single object while the querystring will allow for many unrelated objects.
I can't really answer that question, I tried googling what "is supported" by the model binder and couldn't find any good sources, sorry.
Typically you are supposed to keep the URL clean and simple. And if the request is too complex to move it to post. That is the tradition for RESTful APIs.
I too did a lot of googling before asking here, so I guess there is still not that much out there yet.
What you say about there being a different model binder for QS than the one used for POST body is what I'm thinking also, but I have no clue as to where I should start looking for that kind of information. Maybe I'll have no choice but to dig into the now
open source ASP.NET code !!
I double checked with my colleagues and no one has seen someone using brackets like that for property names. You are supposed to use periods. Well you can try using a custom model binder for that.
It is also a 3 to 1 (me being the 1) that the same model binder is used for both the querystring and the body.
Sorry man, better luck next time.
Well, as I said, if I change to POST, then the paylod is embeded in the body and the Default Model Binder does work.
I can validate that the text of the payload is the same in both cases, so either the Default Model Binder has a quirk when it comes to handling brackets in the querystring, or a different model binder is used.
Also, about square brackets being used instead of periods, I don't know if it's standard or not. Since I'm using some canned components on the client (KendoUI by Telerik), I have to assume/hope that these guys know a thing or two about this as they have
made this their default way of passing filter parameters:
mrlucmorin
0 Points
5 Posts
How to bind this querystring to parameters on an API Controller Action (GET)
Apr 23, 2012 02:49 PM|LINK
Hi,
First of all, I'm very green with anything web, so please bear with me :-)
I'm trying to wrap my head around the various aspects of web applications, and at the same time learning WebAPI.
I'm working with KendoUI on the front end, and following some of their "default" way of doing things (that means using their DataSource object), I request data from a WebAPI controller with a GET.
The URL goes like this:
http://localhost:49337/api/Buildings/Get?filter[logic]=and&filter[filters][0][field]=FolderID&filter[filters][0][operator]=eq&filter[filters][0][value]=2
When looking at the request with Fiddler, I can see in the WebForms tab that Fiddler knows how to "decipher" the querystring:
I've been trying to understand how the default model binder in WebAPI would let me serialize (is that the proper word ?) the querystring to Action parameters, but I've failed miserably so far !
Can anyone offer a word or two of advice how to massage this querystring into proper parameters ?
Thanks a lot.
digitalpacma...
Member
183 Points
148 Posts
Re: How to bind this querystring to parameters on an API Controller Action (GET)
Apr 23, 2012 03:32 PM|LINK
It's using the model binder, and you are probably using characters that are disallowed.
There are properties you can look at to look at the input source (to see what the fields turned into) but I am still on preview 6, so I don't know the specifics, sorry. It has to do with request input parameters.
If the default model binder is not working, then you have to make your own model binder by using action filters.
You would have to read the response yourself, and add the the request parameters how you want your input args named.
mrlucmorin
0 Points
5 Posts
Re: How to bind this querystring to parameters on an API Controller Action (GET)
Apr 23, 2012 05:06 PM|LINK
Hi,
As a further test, I changed the request from a GET to a POST (both on the server side and the client side), and now I can get the Model Binder to work when using the following classes:
public class GridFilter { public string Operator { get; set; } public string Field { get; set; } public string Value { get; set; } } public class GridFilters { public List<GridFilter> Filters { get; set; } public string Logic { get; set; } } //Action signature: [System.Web.Mvc.HttpPost] public IQueryable<Building> Get(WebApi1.Models.GridFilters filter = null) {...}Correct me if I'm wrong, but the difference is that the POST parameters are passed as part of the request body, while the GET parameters are passed in the querystring (It seems to be so from what I see in Fiddler).
Does it mean that the WebAPI default model binder will not work for complex types in querystrings ?
I'd like to understand the difference in WebAPI's binder behavior.
Thanks
digitalpacma...
Member
183 Points
148 Posts
Re: How to bind this querystring to parameters on an API Controller Action (GET)
Apr 23, 2012 06:47 PM|LINK
webapi now uses the mvc model binder, so what works with that will work with webapi.
When you say "difference" I guess you mean qs to post.
QS does not support complex types that well. I am pretty sure there is a different model binder for the QS than the body.
For instance the body only allows a single object while the querystring will allow for many unrelated objects.
I can't really answer that question, I tried googling what "is supported" by the model binder and couldn't find any good sources, sorry.
Typically you are supposed to keep the URL clean and simple. And if the request is too complex to move it to post. That is the tradition for RESTful APIs.
mrlucmorin
0 Points
5 Posts
Re: How to bind this querystring to parameters on an API Controller Action (GET)
Apr 23, 2012 07:01 PM|LINK
Well, thanks for taking a stab at it :-)
I too did a lot of googling before asking here, so I guess there is still not that much out there yet.
What you say about there being a different model binder for QS than the one used for POST body is what I'm thinking also, but I have no clue as to where I should start looking for that kind of information. Maybe I'll have no choice but to dig into the now open source ASP.NET code !!
If anyone else knows about this, let me know.
Cheers
digitalpacma...
Member
183 Points
148 Posts
Re: How to bind this querystring to parameters on an API Controller Action (GET)
Apr 23, 2012 07:24 PM|LINK
I double checked with my colleagues and no one has seen someone using brackets like that for property names. You are supposed to use periods. Well you can try using a custom model binder for that.
It is also a 3 to 1 (me being the 1) that the same model binder is used for both the querystring and the body.
Sorry man, better luck next time.
digitalpacma...
Member
183 Points
148 Posts
Re: How to bind this querystring to parameters on an API Controller Action (GET)
Apr 23, 2012 07:25 PM|LINK
http://dotnetslackers.com/articles/aspnet/Understanding-ASP-NET-MVC-Model-Binding.aspx
mrlucmorin
0 Points
5 Posts
Re: How to bind this querystring to parameters on an API Controller Action (GET)
Apr 23, 2012 09:03 PM|LINK
Well, as I said, if I change to POST, then the paylod is embeded in the body and the Default Model Binder does work.
I can validate that the text of the payload is the same in both cases, so either the Default Model Binder has a quirk when it comes to handling brackets in the querystring, or a different model binder is used.
Also, about square brackets being used instead of periods, I don't know if it's standard or not. Since I'm using some canned components on the client (KendoUI by Telerik), I have to assume/hope that these guys know a thing or two about this as they have made this their default way of passing filter parameters:
http://www.kendoui.com/documentation/framework/datasource/configuration.aspx (look at the serverFiltering description)
I'll look into a custom model binder, if only for the fun of learning something new.
Thanks again.
mrlucmorin
0 Points
5 Posts
Re: How to bind this querystring to parameters on an API Controller Action (GET)
Apr 24, 2012 09:47 PM|LINK
I have entered an issue on codeplex about this behavior:
http://aspnetwebstack.codeplex.com/workitem/96
I'm sure the behavior should be consistent between both GET and POST.
Cheers