CustomQueryParametersBinder:
using complex_json_can_not_bind_successful.Models;
using Microsoft.AspNetCore.Mvc.ModelBinding;
namespace complex_json_can_not_bind_successful
{
public class CustomQueryParametersBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
var query = bindingContext.HttpContext.Request.Query;
var pageValue = query["page"].FirstOrDefault();
var pageSizeValue = query["page_size"].FirstOrDefault();
var sortByValues = query.Where(q => q.Key.StartsWith("sortBy")).ToDictionary(k => k.Key, v => v.Value.ToString());
var result = new QueryParameters
{
Page = int.TryParse(pageValue, out var page) ? page : 1,
PageSize = int.TryParse(pageSizeValue, out var pageSize) ? pageSize : 10,
SortBy = sortByValues
.GroupBy(kv => int.Parse(kv.Key.Split('[')[1].Split(']')[0]))
.Select(g => new SortOption
{
Key = g.FirstOrDefault(kv => kv.Key.Contains("key")).Value,
Order = g.FirstOrDefault(kv => kv.Key.Contains("order")).Value
})
.ToList()
};
bindingContext.Result = ModelBindingResult.Success(result);
return Task.CompletedTask;
}
}
}
How to use it:
[HttpGet("method2")]
public IActionResult Get2([ModelBinder(BinderType = typeof(CustomQueryParametersBinder))] QueryParameters queryParameters)
{
return Ok(queryParameters);
}
You can use sample code like this:

[ApiController]
[Route("[controller]")]
public class TestController : Controller
{
[HttpGet]
public IActionResult Get([FromQuery] int page, [FromQuery(Name = "page_size")] int pageSize)
{
var sortBy = Request.Query
.Where(q => q.Key.StartsWith("sortBy"))
.GroupBy(kv => int.Parse(kv.Key.Split('[')[1].Split(']')[0]))
.Select(g => new SortOption
{
Key = g.FirstOrDefault(kv => kv.Key.Contains("key")).Value.ToString(),
Order = g.FirstOrDefault(kv => kv.Key.Contains("order")).Value.ToString()
})
.ToList();
var queryParameters = new QueryParameters
{
Page = page,
PageSize = pageSize,
SortBy = sortBy
};
// Your logic here
return Ok(queryParameters);
}
}
Models:
public class SortOption
{
public string Key { get; set; }
public string Order { get; set; }
}
public class QueryParameters
{
public int Page { get; set; }
public int PageSize { get; set; }
public List<SortOption> SortBy { get; set; }
}