如何让最小 API 绑定查询字符串中的数组

前言

在上次的文章中,我们实现了《让 ASP.NET Core 支持绑定查询字符串中的数组》:

[HttpGet]
public string Get([FromQuery][ModelBinder(BinderType = typeof(IntArrayModelBinder))] int[] values)
{
    return string.Join(" ", values.Select(p => p.ToString()));
}

但是,同样的实现方式,在最小 API 上却报错:

如何让最小 API 绑定查询字符串中的数组_第1张图片

那么,使用最小 API 能实现相同功能呢吗?

深入探究

实现扩展方法

通过错误提示,我们发现最小 API 在查找类型的静态 TryParse 方法:

No public static bool int[].TryParse(string, out int[]) method found for values.”

于是,我们尝试为int[]类型创建TryParse扩展方法:

public static class IntArrayExtentions
{ 
    public static bool TryParse(this int[] obj, string value, out int[] result)
    {
        result = value.Trim('[', ']').Split(',').Select(str => int.Parse(str)).ToArray();
        return true;
    }
}

但是,测试发现没有任何效果。

通过调用堆栈:

如何让最小 API 绑定查询字符串中的数组_第2张图片

我们找到了查找静态 TryParse 方法的源代码:

private MethodInfo? GetStaticMethodFromHierarchy(Type type, string name, Type[] parameterTypes, Func validateReturnType)
{
    bool IsMatch(MethodInfo? method) => method is not null && !method.IsAbstract && validateReturnType(method);

    var methodInfo = type.GetMethod(name, BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy, parameterTypes);

type.GetMethod方法是无法获取扩展方法的。

看来此路不通!

自定义类型

既然扩展方法不行,那只能使用定义了静态 TryParse 方法的自定义类型了:

public class DemoDto
{
    public int[] Array { get; set; }
    public static bool TryParse(string value, out DemoDto result)
    {
        result = new DemoDto { Array = value.Trim('[', ']').Split(',').Select(str => int.Parse(str)).ToArray() };
        return true;
    }
}

app.MapGet("/",
    (DemoDto values) =>
{
    return string.Join(" ", values.Array.Select(p => p.ToString()));
});

再次运行,执行成功:

d91edd13ed2e6a6cd2fd064d0fcc96a9.png

结论

对于路由、查询和标头绑定源,最小 API 通过类型的静态 TryParse 方法来绑定自定义类型。

TryParse 具有两个 API:

public static bool TryParse(string value, out T result);
public static bool TryParse(string value, IFormatProvider provider, out T result);

添加微信号【MyIO666】,邀你加入技术交流群

你可能感兴趣的:(java,python,c#,.net,android)