既定のモデル バインダーをカスタマイズする方法を読んだ後、このコードはプロパティの並べ替えのトリックを実行し、毎回目的のバインド順序を提供する可能性があると思います。基本的に、ID プロパティを最初にバインドできるようにする (したがって、View Model で「ロード」をトリガーできるようにする) ことで、モデル バインディング プロセスの残りの部分を基本的にマージとして機能させることができます。
''' <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