How to pass in Uri complex objects without using custom ModelBinders or any serialization?
Do you wonder why I publish such an article?
Well, recently it happened to me to ask to a legacy information system in which I was to find information of users only with their name and their first name…
Yes yes using their name first name:).
I had to send to the WebApi a list of name/first name, the whole paginated, how did I make it?
At the beginning I had the idea to create my search model object in JSON which I would have to serialize while passing it in the URL, then, I had the idea to create an object with a string property containing the list of the names/firstnames the whole “decorated with separators” then split it in the WebAPI with a custom ModelBinder. Finally I decided I’d rather understand how to pass in the Uri more or less complex objects without using of ModelBinder or serialisation?.
Here what I did:
I tested 2 scenarios, the first with a list of “Person” and a second with a little more complex object “ListOfPersons”.
Before starting, as a reminder, I just want to remind you how we pass in a Uri a string collection.
namespace QueryStringDemo.Models { public class Person { public string FirstName { get; set; } public string LastName { get; set; } } }
namespace QueryStringDemo.Models { public class ListOfPersons { public int? PageNumber { get; set; } public int? PageSize { get; set; } public ListPersons { get; set; } } }
using QueryStringDemo.Models; using System.Collections.Generic; using System.Web.Http; namespace QueryStringDemo.Controllers { [RoutePrefix("api/demo")] public class DemoController : ApiController { [Route("simplelist")] [HttpGet] public IHttpActionResult Get([FromUri]Liststrings) { return Ok(); } [Route("simplelistOfpersons")] [HttpGet] public IHttpActionResult Get([FromUri]List listOfPersons) { return Ok(); } [Route("complexlistOfpersons")] [HttpGet] public IHttpActionResult Get([FromUri]ListOfPersons listOfPersons) { return Ok(); } } }
1- Scenario 1, reminder, string collection :
Uri :
Result in code :
Note that you have to use the attribute [FromUri], it provides deserialization to the target object from a complex object that comes from the queryString.
2- Scenario 2, collection of person object :
Uri :
Result in code :
Note that the object is in fact an array, an array like this
?[index].PropertyName=Value
3- Scenario 3, a more complex collection of person object :
Uri :
Result in code :
Note that it works also with an array,
our object looks like this :
?PropertyName1=value&PropertyName2=value&PropertyName3[index].SubPropertyName1=value&PropertyName3[index].SubPropertyName2=value
Finally we have demystified how queryString native serialization/deserialization works, was it so complicated ? 🙂