好的,在阅读了如何自定义默认模型绑定器之后,我认为这段代码可以完成对属性进行排序的技巧,并且每次都会给我所需的绑定顺序。基本上允许我首先绑定标识属性(从而允许我让我的视图模型触发“加载”),从而允许模型绑定过程的其余部分基本上作为合并运行!
''' <summary>
''' A derivative of the DefaultModelBinder that ensures that desired properties are put first in the binding order.
''' </summary>
''' <remarks>
''' When view models can reliably expect a bind of their key identity properties first, they can then be designed trigger a load action
''' from their repository. This allows the remainder of the binding process to function as property merge.
''' </remarks>
Public Class BindIdFirstModelBinder
Inherits DefaultModelBinder
Private commonIdPropertyNames As String() = {"Id"}
Private sortedPropertyCollection As ComponentModel.PropertyDescriptorCollection
Public Sub New()
MyBase.New()
End Sub
''' <summary>
''' Use this constructor to declare specific properties to look for and move to top of binding order.
''' </summary>
''' <param name="propertyNames"></param>
''' <remarks></remarks>
Public Sub New(propertyNames As String())
MyBase.New()
commonIdPropertyNames = propertyNames
End Sub
Protected Overrides Function GetModelProperties(controllerContext As ControllerContext, bindingContext As ModelBindingContext) As ComponentModel.PropertyDescriptorCollection
Dim rawCollection = MyBase.GetModelProperties(controllerContext, bindingContext)
Me.sortedPropertyCollection = rawCollection.Sort(commonIdPropertyNames)
Return sortedPropertyCollection
End Function
End Class
然后,我可以注册它来代替我的 DefaultModelBinder,并提供我希望“浮动”到 ModelBinding 进程顶部的最常见的属性名称......
Sub Application_Start()
RouteConfig.RegisterRoutes(RouteTable.Routes)
BundleConfig.RegisterBundles(BundleTable.Bundles)
' etc... other standard config stuff omitted...
' override default model binder:
ModelBinders.Binders.DefaultBinder = New BindIdFirstModelBinder({"Id", "WorkOrderId", "CustomerId"})
End Sub