I want to map List<T>
from query string in .NET 8 Minimal API.
Tried like this:
public record ColumnFilterDto(string Column, object Value);
app.MapGet("/", (
[FromQuery] List<ColumnFilterDto> columnFilters,
[FromQuery] int? page = 1,
[FromQuery] int? pageSize = 20) =>
{
})
.WithOpenApi();
but this generates an complilation error:
ASP0020: Parameter 'columnFilters' of type List should define a bool TryParse(string, IFormatProvider, out List) method, or implement IParsable<List>
Tried to implement IParsable for List like this:
public record ColumnFilterDto(string Column, object Value) : IParsable<List<ColumnFilterDto>>
but it's not possible, compilator say's the 'IParsable<TSelf>' requires the 'TSelf' type parameter to be filled with the derived type 'ColumnFilterDto'
Tried also to implement IParsable:
public record ColumnFilterDto(string Column, object Value) : IParsable<ColumnFilterDto>
{
public static ColumnFilterDto Parse(
string s,
IFormatProvider? provider)
{
var arr = s.Split(":");
return new ColumnFilterDto(arr[0], arr[1]);
}
public static bool TryParse(
string? s ,
IFormatProvider? provider,
out ColumnFilterDto result)
{
var arr = s.Split(":");
result = new ColumnFilterDto(arr[0], arr[1]);
return true;
}
}
Also found [AsParameters] attribute in MSDN, but it's not working for List
public record ColumnFilterDto(string Column, object Value) : IParsable<ColumnFilterDto>
{
public static ColumnFilterDto Parse(
string s,
IFormatProvider? provider)
{
var arr = s.Split(":");
return new ColumnFilterDto(arr[0], arr[1]);
}
public static bool TryParse(
string? s ,
IFormatProvider? provider,
out ColumnFilterDto result)
{
var arr = s.Split(":");
result = new ColumnFilterDto(arr[0], arr[1]);
return true;
}
}
app.MapGet("/", (
[AsParameters] List<ColumnFilterDto> columnFilters,
[FromQuery] int? page = 1,
[FromQuery] int? pageSize = 20) =>
{
})
.WithOpenApi();
app.Run();
the code above generates:
InvalidProgramException: Common Language Runtime detected an invalid program. System.Reflection.Emit.DynamicMethod.CreateDelegate(Type delegateType, object target)
I know that minimal api can only bind simple types, it doesnt have binder like ASP.NET Controllers, but how can I make it work in minimal api?
Check out the Parameter Binding in Minimal API apps: Bind arrays and string values from headers and query strings doc. According to it you should use array instead of List
:
app.MapGet("/barr", (
[FromQuery] ColumnFilterDto[] columnFilters,
[FromQuery] int? page = 1,
[FromQuery] int? pageSize = 20) => columnFilters)
.WithOpenApi();
Which works with your ColumnFilterDto : IParsable<ColumnFilterDto>
implementation.
Also I would recommend to use POST
query and pass the filter as JSON body which will make things easier and you will not need to bother with query string size limits if you will have a lot of filters.