.NET 最小 API 映射 List<T> 参数作为 [FromQuery]

问题描述 投票:0回答:1

我想从 .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中工作?

c# .net asp.net-core query-string minimal-apis
1个回答
1
投票

查看最小 API 应用程序中的参数绑定:从标头和查询字符串中绑定数组和字符串值文档。根据它,你应该使用数组而不是

List

app.MapGet("/barr", (
        [FromQuery] ColumnFilterDto[] columnFilters,
        [FromQuery] int? page = 1,
        [FromQuery] int? pageSize = 20) => columnFilters)
    .WithOpenApi();

这适用于您的

ColumnFilterDto : IParsable<ColumnFilterDto>
实施。

此外,我建议使用

POST
查询并将过滤器作为 JSON 主体传递,这将使事情变得更容易,如果您有很多过滤器,您将不需要担心查询字符串大小限制。

© www.soinside.com 2019 - 2024. All rights reserved.