通过上述代码我们可知推断来源结果只有三种:Body、Path、Query。因为我们未显式配置绑定来源,所以走参数推断来源,然后首先判断是否为复杂类型,判断条件是如果AllowInferringBindingSourceForCollectionTypesAsFromQuery配置为true,同时为集合类型说明来源为Body。此时我们无论是否显式配置绑定集合类型是否来源于FromQuery,肯定不满足这两个条件,接着执行metadate.IsComplexType,很显然Employee为复杂类型,我们再次通过源码也可证明,在获取模型元数据时,通过!TypeDescriptor.GetConverter(typeof(ModelType)).CanConvertFrom(typeof(string))判断是否为复杂类型,所以此时返回绑定来源于Body,所以出现415,问题已经分析的很清楚了,来,最终,我们给ApiController特性本质下一个结论:
通过ApiController修饰控制器,内置实现了6个默认约定,其中最重要的两个约定则是,其一解决模型自动验证,其二则是当未配置绑定来源,执行参数推断来源,但是,但是,这个仅仅只是针对Body、Path、Query而言。
当控制器方法上参数为字典或集合时,如果请求参数来源于URL也就是查询字符串请显式配置AllowInferringBindingSourceForCollectionTypesAsFromQuery为true,否则会推断绑定来源为Body,从而响应415。
当控制器方法上参数为复杂类型时,如果请求参数来源于Body,可以无需显式配置绑定来源,如果参数来源为URL也就是查询字符串,请显式配置参数绑定来源【FromQuery】,如果参数来源于表单,请显式配置参数绑定来源【FromForm】,否则会推断绑定为Body,从而响应415。
总结
本文比较详细的阐述了.NET Core中的模型绑定系统、模型绑定原理、自定义模型绑定原理、混合绑定等等,其实还有一些基础内容我还未写出,后续有可能我接着研究并补上,.NET Core中强大的模型绑定支持以及灵活性控制都是.NET MVC/Web Api不可比拟的,虽然很基础但是又有多少人知道并且了解过这些呢,同时针对ApiController特性确实给我们省去了不必要的代码,但是带来的参数来源推断让我们有点懵逼,如果不看源码,断不可知这些,我个人认为针对添加ApiController特性后的参数来源推断,没什么鸟用,强烈建议显式配置绑定来源,也就不必记住上述结论了,本篇文章耗费我三天时间所写,修修补补,其中所带来的价值,一个字:值。
您可能感兴趣的文章: