前言
在上次的文章中,我们实现了《让 ASP.NET Core 支持绑定查询字符串中的数组》:
[HttpGet]
public string Get([FromQuery][ModelBinder(BinderType = typeof(IntArrayModelBinder))] int[] values)
{return string.Join(" ", values.Select(p => p.ToString()));
}
但是,同样的实现方式,在最小 API 上却报错:
那么,使用最小 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;}
}
但是,测试发现没有任何效果。
通过调用堆栈:
我们找到了查找静态 TryParse 方法的源代码:
private MethodInfo? GetStaticMethodFromHierarchy(Type type, string name, Type[] parameterTypes, Func<MethodInfo, bool> 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()));
});
再次运行,执行成功:
结论
对于路由、查询和标头绑定源,最小 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】,邀你加入技术交流群