When I use the GET
API to send a complex JSON format, the backend cannot obtain the data correctly.
This my query string data:
{
"page": 1,
"page_size": 10,
"sortBy":
[
{"key": "reservation_no", "order": "desc"},
{"key": "pr_no", "order": "desc"},
{"key": "pr_item", "order": "asc"}
]
}
Then it will be converted to this format
?page=1&page_size=11&sortBy[0][key]=reservation_no&sortBy[0][order]=desc&sortBy[1][key]=pr_no&sortBy[1][order]=desc&sortBy[2][key]=pr_item&sortBy[2][order]=asc
My backend can get page
and page_size
, but sortBy
is null.
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; }
}