我希望得到一些关于在MVC和WebAPI之间共享自定义模型绑定器的最佳方法的建议。我这样做的方式虽然功能齐全,但看起来过于复杂,我相当肯定必须有更好的方法。
我有一个混合应用程序,它使用MVC来提供应用程序UI,部分视图用于站点的动态部分,API提供与第三方应用程序使用的JSON相同的模型。我想要的是能够使用相同的代码来过滤Web API和MVC的模型列表。
目前我有一个binder类,它实现了Web.Mvc.IModelBinder(用于MVC)和Http.ModelBinding.IModelBinder(用于Web API)。然后,该类为每个接口定义两个BindModel函数......
Public Function BindModel(actionContext As Http.Controllers.HttpActionContext, bindingContext As Http.ModelBinding.ModelBindingContext) As Boolean Implements Http.ModelBinding.IModelBinder.BindModel
Dim request As System.Net.Http.HttpRequestMessage = actionContext.Request
Dim qs = request.GetQueryNameValuePairs.ToLookup(Function(x) x.Key.ToLower, Function(x) x.Value)
bindingContext.Model = GetFilter(qs)
Return True
End Function
Public Function BindModel(controllerContext As Web.Mvc.ControllerContext, bindingContext As Web.Mvc.ModelBindingContext) As Object Implements Web.Mvc.IModelBinder.BindModel
Dim request As HttpRequestBase = controllerContext.RequestContext.HttpContext.Request
Dim qs = request.QueryString
Return GetFilter(qs.ToLookup)
End Function
这些函数基本上从各自的Request集合中提取ILookup,这样我就可以使用单个函数获取过滤参数。 GetFilter函数定义为...
Public Function GetFilter(lookup As ILookup(Of String, String)) As MyCustomFilter
Dim filter As New MyCustomFilter
filter.Offset = ConvertToInteger(lookup("offset").FirstOrDefault())
filter.Count = ConvertToInteger(lookup("count").FirstOrDefault())
filter.Keyword = lookup("q").FirstOrDefault()
filter.Country = ConvertToInteger(lookup("country").FirstOrDefault())
filter.State = ConvertToInteger(lookup("state").FirstOrDefault())
'etc...
Return filter
End Function
要附加WebAPI的绑定器,我必须创建一个BinderProvider类,就像这样......
Public Class MyCustomFilterBinderProvider
Inherits Http.ModelBinding.ModelBinderProvider
Public Overrides Function GetBinder(configuration As Http.HttpConfiguration, modelType As Type) As Http.ModelBinding.IModelBinder
Return New MyCustomFilterBinder
End Function
End Class
...并装饰过滤器类以使其坚持......
<System.Web.Http.ModelBinding.ModelBinderAttribute(GetType(MyCustomFilterBinderProvider))>
Public Class MyCustomFilter
要将自定义绑定器附加到MVC,我将以下内容添加到我的启动代码中......
ModelBinders.Binders.Add(GetType(MyNamespace.MyCustomFilter), New MyNamespace.MyCustomFilterBinder)
虽然这一切都正常,但似乎过于复杂。我不知道怎么回事?我错过了这种“正确的方法”吗?
任何建议都会受到最高的赞赏。