publicclassSnakeCaseQueryValueProviderFactory : IValueProviderFactory { public Task CreateValueProviderAsync(ValueProviderFactoryContext context) { if (context == null) { thrownew ArgumentNullException(nameof(context)); }
var valueProvider = new SnakeCaseQueryValueProvider( BindingSource.Query, context.ActionContext.HttpContext.Request.Query, CultureInfo.CurrentCulture);
通过研究Asp.net core的源码,将会发现ModelBinding上下文有一个IValueProvider列表,每次进行模型绑定获取参数值时,都会遍历其中的是适配器列表,与具体的参数名称进行对比从而获取参数值。因此如果大家想要提升一下自定义适配器的优先级,可以使用ops.ValueProviderFactories.Insert(0, new SnakeCaseQueryValueProviderFactory())方法,将其放到列表的第一个。实际上框架中自带一些默认的IValueProvider,如QueryStringValueProvider,FormValueProvider、RouteValueProviderFactory、JQueryFormValueProviderFactory,如果大家觉得作为一个RestfulApi应用,像JQueryFormValueProviderFactory, FormValueProvider这种东西不需要,我们也可以移除掉略微提升一些性能,当然,如果QPS达不到一定量几乎感觉不到性能提升。
逻辑很简单,Api描述上下文中的参数描述类中有个BindSource类型的字段,通过这个Source字段可以判断这个参数的类型,它包括Body、Form、Query、ModelBinding等等类型。这里有一点需要注意的是,官方文档中对ModelBinding的定义是:A BindingSource for model binding. Includes form-data, query-string and route data from the request.。在RestfulApi场景中,form-data肯定是用不到,因此只需注意一下route data就行了,这是另一个话题,这里就不深究了。