SHARE:

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 List Persons { 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]List strings)
        {
            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 :

scenario1-url

Result in code :

scenario1-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 :

scenario2-url

Result in code :

scenario2-code-1

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 :

scenario3-url

Result in code :

scenario3-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 ? 🙂

Written by

anthonygiretti

Anthony is a specialist in Web technologies (14 years of experience), in particular Microsoft .NET and learns the Cloud Azure platform. He has received twice the Microsoft MVP award and he is also certified Microsoft MCSD and Azure Fundamentals.