Search code examples
c#asp.net-corecontrollerhttpapi

Passing Complex Filter throw HttpApi in Asp.Net Core 3.1


I've build an Asp.Net Core Controller and I would like to pass Data throw the Url to my Backend.

Throw my URI I would like to paste: filter:"[[{"field":"firstName","operator":"eq","value":"Jan"}]]

So my URI looks like: https://localhost:5001/Patient?filter=%5B%5B%7B%22field%22%3A%22firstName%22,%22operator%22%3A%22eq%22,%22value%22%3A%22Jan%22%7D%5D%5D

and my Controller:

[HttpGet]
public ActionResult<bool> Get(
    [FromQuery] List<List<FilterObject>> filter = null)
{
            return true;
}

and my FilterObject looks like:

public class FilterObject
    {
        public string Field { get; set; }
        public string Value { get; set; }
        public FilterOperator Operator { get; set; } = FilterOperator.Eq;

    }

The Problem now is that my Data from the URL is not deserialized in my filter Parameter.

Do anyone have an Idea? Thans for helping.

Best Regards


Solution

  • Throw my URI I would like to paste: filter:"[[{"field":"firstName","operator":"eq","value":"Jan"}]]

    You can achieve the requirement by implementing a custom model binder, the following code snippet is for your reference.

    public class CustomModelBinder : IModelBinder
    {
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
            {
                throw new ArgumentNullException(nameof(bindingContext));
            }
    
            // ...
            // implement it based on your actual requirement
            // code logic here
            // ...
    
            var options = new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true
            };
            options.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase));
    
            var model = JsonSerializer.Deserialize<List<List<FilterObject>>>(bindingContext.ValueProvider.GetValue("filter").FirstOrDefault(), options);
    
            bindingContext.Result = ModelBindingResult.Success(model);
            return Task.CompletedTask;
        }
    }
    

    Controller action

    [HttpGet]
    public ActionResult<bool> Get([FromQuery][ModelBinder(BinderType = typeof(CustomModelBinder))]List<List<FilterObject>> filter = null)
    {
    

    Test Result

    enter image description here