我想从 .NET 8 Minimal API 中的查询字符串映射
List<T>
。
尝试过这样的:
public record ColumnFilterDto(string Column, object Value);
app.MapGet("/", (
[FromQuery] List<ColumnFilterDto> columnFilters,
[FromQuery] int? page = 1,
[FromQuery] int? pageSize = 20) =>
{
})
.WithOpenApi();
但这会产生编译错误:
ASP0020: Parameter 'columnFilters' of type List should define a bool TryParse(string, IFormatProvider, out List) method, or implement IParsable<List>
尝试为 List 实现 IParsable,如下所示:
public record ColumnFilterDto(string Column, object Value) : IParsable<List<ColumnFilterDto>>
但这是不可能的,编译器说是
the 'IParsable<TSelf>' requires the 'TSelf' type parameter to be filled with the derived type 'ColumnFilterDto'
还尝试实现 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;
}
}
还在MSDN中找到了[AsParameters]属性,但它不适用于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();
上面的代码生成:
InvalidProgramException: Common Language Runtime detected an invalid program. System.Reflection.Emit.DynamicMethod.CreateDelegate(Type delegateType, object target)
我知道最小的API只能绑定简单类型,它没有像ASP.NET控制器那样的绑定器,但是我怎样才能让它在最小的API中工作?
查看最小 API 应用程序中的参数绑定:从标头和查询字符串中绑定数组和字符串值文档。根据它,你应该使用数组而不是
List
:
app.MapGet("/barr", (
[FromQuery] ColumnFilterDto[] columnFilters,
[FromQuery] int? page = 1,
[FromQuery] int? pageSize = 20) => columnFilters)
.WithOpenApi();
这适用于您的
ColumnFilterDto : IParsable<ColumnFilterDto>
实施。
此外,我建议使用
POST
查询并将过滤器作为 JSON 主体传递,这将使事情变得更容易,如果您有很多过滤器,您将不需要担心查询字符串大小限制。