在上次的文章中,我们实现了《让 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 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】,邀你加入技术交流群