前言
在上次的文章中,我們實現了《讓 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】,邀你加入技術交流群