Мне удалось решить эту проблему с помощью пользовательских связывателей.Вам нужно будет добавить свойство для ссылки на родительский объект, например NumberOfRooms.В моем случае я фактически создал делегат, который ссылался на подпрограмму в родительском объекте.Заранее извиняюсь за проблемы с кодом и форматированием VB, которые возникают у меня с stackoverflow.
- Создайте свойство NumberOfRooms для дочернего объекта.
- Создайте пользовательский механизм связывания модели для дочернего объекта.учебный класс.Этот механизм связывания будет выполнять несколько действий: a) Вставить значение для NumberOfRooms (в моем случае я назначу делегата). B) Сохранить метаданные / информацию о ключе в словаре контроллера, который будет использоваться позже для повторной проверки.
Например:
Public Class RoomDetail_Binder
Inherits DefaultModelBinder
Protected Overrides Function CreateModel(controllerContext As ControllerContext, bindingContext As ModelBindingContext, modelType As Type) As Object
Dim theObj As Quote_Equipment_Model = MyBase.CreateModel(controllerContext, bindingContext, modelType)
Dim theParent As StayDetails= controllerContext.HttpContext.Items("StayDetails")
If Not IsNothing(theParent) Then
theObj.NumberOfRooms=theParent.NumberOfRooms
End If
Return theObj
End Function
Protected Overrides Sub OnModelUpdated(controllerContext As ControllerContext, bindingContext As ModelBindingContext)
MyBase.OnModelUpdated(controllerContext, bindingContext)
Dim theMetadataList As List(Of MetaDataPair)
If Not controllerContext.HttpContext.Items.Contains("MetadataList") Then
theMetadataList = New List(Of MetaDataPair)
controllerContext.HttpContext.Items.Add("MetadataList", theMetadataList)
Else
theMetadataList = controllerContext.HttpContext.Items("MetadataList")
End If
theMetadataList.Add(New MetaDataPair With {.Metadata = bindingContext.ModelMetadata, .BindingModelName = bindingContext.ModelName})
End Sub
End Class
Обратите внимание, что MetadataList просто
Public Class MetaDataPair
Public Property BindingModelName As String
Public Property Metadata As ModelMetadata
End Class
Далее я создаю пользовательский связыватель для родительского объекта: Это также делает несколько вещей:
a) Сохраните родительский объект в controlcontext, чтобы он мог использоваться дочерним объектом.б) Повторная проверка дочернего объекта.
Открытый класс StayDetails_Binder Наследует DefaultModelBinder
Protected Overrides Function CreateModel(controllerContext As ControllerContext, bindingContext As ModelBindingContext, modelType As Type) As Object
Dim theObj As StayDetails = MyBase.CreateModel(controllerContext, bindingContext, modelType)
controllerContext.HttpContext.Items("StayDetails") = theObj
Return theObj
End Function
Public Overrides Function BindModel(controllerContext As ControllerContext, bindingContext As ModelBindingContext) As Object
Dim theObj As StayDetails = MyBase.BindModel(controllerContext, bindingContext)
Dim theMetadataList As List(Of MetaDataPair) = CType(controllerContext.HttpContext.Items("MetadataList"), List(Of MetaDataPair))
For Each Metadata In theMetadataList
For Each result As ModelValidationResult In ModelValidator.GetModelValidator(Metadata.Metadata, controllerContext).Validate(Nothing)
Dim key As String = CreateSubPropertyName(Metadata.BindingModelName, result.MemberName)
If Not bindingContext.ModelState(key).Errors.Any(Function(ent) ent.ErrorMessage = result.Message) Then
bindingContext.ModelState.AddModelError(key, result.Message)
End If
Next
Next
Return theObj
End Function
Конечный класс
Украсьте свой подкласс соответствующим образом
Public Class RoomDetail
Установите свой контроллер так, чтобы он использовал пользовательское связующее:
(имя вашего параметра здесь)
Убедитесь, что для вашего валидатора установлено значение SUCCESS, если вы проверяете его без заполненного свойства NumberOfRooms.Привязка выполнит ваши валидаторы дважды для вашего дочернего класса.Первый раз, когда свойство заполнено, а затем снова, когда свойство заполнено.