编程添加属性在运行时的MVC模式 [英] Programmatically adding properties to an MVC model at runtime
问题描述
我想创建编程时,应用程序运行在我的模型属性。我试着遵循达林季米特洛夫回答这个帖子上的How在MVC 3基于XML文件动态创建控件
I am trying to create properties in my model programmatically when the application is run. I've tried to follow the answer by Darin Dimitrov on this post How to create controls dynamically in MVC 3 based on an XML file
我想在code转换为VB.NET。到目前为止,我有...
I am trying to convert the code to VB.NET. So far I have...
型号:
Public Class MyViewModel
Public Property Controls As ControlViewModel()
End Class
Public MustInherit Class ControlViewModel
Public MustOverride ReadOnly Property Type As String
Public Property Visible As Boolean
Public Property Label As String
Public Property Name As String
End Class
Public Class TextBoxViewModel
Inherits ControlViewModel
Public Overrides ReadOnly Property Type As String
Get
Return "textbox"
End Get
End Property
Public Property Value As String
End Class
Public Class CheckBoxViewModel
Inherits ControlViewModel
Public Overrides ReadOnly Property Type As String
Get
Return "checkbox"
End Get
End Property
Public Property Value As Boolean
End Class
控制器:
Function Test() As ActionResult
Dim model = New MyViewModel() With { _
.Controls = New ControlViewModel() {New TextBoxViewModel() With { _
.Visible = True, _
.Label = "text label", _
.Name = "TextBox1", _
.Value = "Text appears here" _
}, New CheckBoxViewModel() With { _
.Visible = True, _
.Label = "check label", _
.Name = "CheckBox1", _
.Value = True _
}
}}
Return View("Test", model)
End Function
<httpPost()>
Function Test(model As MyViewModel) As ActionResult
Return View("Test", model)
End Function
查看:
@ModelType MyApp.DomainModel.MyTest.MyViewModel
@Code
Using Html.BeginForm()
Dim i As Integer
For i = 0 To Model.Controls.Length - 1
End Code
<div>
@Html.EditorFor(Function(model) model.Controls(i))
</div>
@Code
Next
End Code
<input type="submit" value="OK" />
@Code
End Using
End Code
文本框编辑模板:
TextBox Editor Template:
@modeltype MyApp.DomainModel.MyTest.TextBoxViewModel
@Html.LabelFor(Function(model) model.Value, Model.Label)
@Html.TextBoxFor(Function(model) model.Value)
复选框编辑模板:
Checkbox Editor Template:
@modeltype MyApp.DomainModel.MyTest.CheckBoxViewModel
@Html.LabelFor(Function(model) model.Value, Model.Label)
@Html.CheckBoxFor(Function(model) model.Value)
自定义模型绑定:
Custom Model Binder:
Public Class ControlModelBinder
Inherits DefaultModelBinder
Public Overrides Function BindModel(controllerContext As ControllerContext, bindingContext As ModelBindingContext) As Object
Dim type = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".Type")
Dim name = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".Name")
Dim value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".Value")
If type IsNot Nothing AndAlso value IsNot Nothing Then
Select Case type.AttemptedValue
Case "textbox"
Return New TextBoxViewModel() With { _
.Name = name.AttemptedValue, _
.Value = value.AttemptedValue _
}
Case "checkbox"
Return New CheckBoxViewModel() With { _
.Name = name.AttemptedValue, _
.Value = Boolean.Parse(value.AttemptedValue.Split(","c).First()) _
}
End Select
End If
Throw New NotImplementedException()
End Function
End Class
Global.asax中:
Global.asax:
ModelBinders.Binders.Add(GetType(MyTest.ControlViewModel), New MyTest.ControlModelBinder())
当我运行应用程序,自定义模型绑定类型和名称的变量似乎并没有正确设置。
When I run the application, in the custom model binder the type and name variable don't seem to be set correctly.
还有什么我做错了?
推荐答案
您缺少在主视图2隐藏字段:
You are missing 2 hidden fields in your main view:
@ModelType MyApp.DomainModel.MyTest.MyViewModel
@Using Html.BeginForm()
For i = 0 To Model.Controls.Length - 1
@<div>
@Html.HiddenFor(Function(model) model.Controls(i).Type)
@Html.HiddenFor(Function(model) model.Controls(i).Name)
@Html.EditorFor(Function(model) model.Controls(i))
</div>
Next
@<input type="submit" value="OK" />
End Using
在您的code,你只有一个 EditorFor
呼吁控件
属性,但你永远不指定类型通过一个隐藏字段,用于由自定义模型绑定的控件。
In your code you only have a single EditorFor
call for the Controls
property but you never specify the type of the control through a hidden field which is used by the custom model binder.
更新:
我也固定其中载有缺陷,因为它是更好地覆盖CreateModel方法,而不是BindModel原来的模型绑定:
I have also fixed the original model binder which contained a bug as it is better to override the CreateModel method instead of the BindModel:
Public Class ControlModelBinder
Inherits DefaultModelBinder
Protected Overrides Function CreateModel(controllerContext As ControllerContext, bindingContext As ModelBindingContext, modelType As Type) As Object
Dim type = bindingContext.ValueProvider.GetValue(Convert.ToString(bindingContext.ModelName) & ".Type")
If type Is Nothing Then
Throw New Exception("The type must be specified")
End If
Dim model As Object = Nothing
Select Case type.AttemptedValue
Case "textbox"
If True Then
model = New TextBoxViewModel()
Exit Select
End If
Case "checkbox"
If True Then
model = New CheckBoxViewModel()
Exit Select
End If
Case "ddl"
If True Then
model = New DropDownListViewModel()
Exit Select
End If
Case Else
If True Then
Throw New NotImplementedException()
End If
End Select
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(Function() model, model.[GetType]())
Return model
End Function
End Class
这篇关于编程添加属性在运行时的MVC模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!