MVC 模型未绑定到 HTTPPost 操作
MVC Model not binding to HTTPPost action
每当我从 Respond.vbhtml
页面提交我的表单时,我在控制器中的 Respond_post
函数就会像它应该的那样被调用;但是,FormsRespondModel
中传递的项目是空的。
为什么我的 post 操作没有按预期填充我的 FormsRespondModel?
FormsRespondModel.vb
Public Class FormsRespondModel
Public Property form As cihForm
Public Property lists As cihLists = New cihLists()
Public Property subOrgs As List(Of cihOrganizationSub)
Public Property Events As List(Of cihEvent)
Public Sub New()
End Sub
Public Sub New(formId As String)
form = New cihForm()
form.loadForm(Guid.Parse(formId))
lists.loadOrganizationSubs(ZenCommon.CurrentOrgId, ZenCommon.CurrentUserId)
Dim emptyList() As String = {}
Dim eventsearchList As cihEventSearch = New cihEventSearch(ZenCommon.CurrentOrgId, "", DateTime.Now, ZenCommon.Date2050, True, emptyList, emptyList, emptyList)
Events = eventsearchList.eventList
subOrgs = lists.organizationSubs
End Sub
End Class
Respond.vbhtml
@ModelType CheckImHere.Student.FormsRespondModel
@Using Html.BeginForm()
@html.Hidden(Model.form.formId.ToString())
@For Each fld As Field In Model.form.fields
If fld.fieldTypeId = "text" Then
@<li>
<h4>@fld.title</h4>
<em>@fld.description</em>
<input type="text" placeholder="" value="@fld.response"/>
<em>@fld.isRequired</em>
</li>
End If
If fld.fieldTypeId = "para" Then
@<li>
<h4>@fld.title</h4>
<em>@fld.description</em>
@html.textarea(fld.response)
<em>@fld.isRequired</em>
</li>
End If
Next
<input type="submit" name="cmdSubmit" value="Submit" id="cmdSubmit"/>
End Using
RespondController.vb
<HttpPost>
<ActionName("Respond")>
Function Respond_post(viewModel As FormsRespondModel) As ActionResult
Return View("Respond", viewModel)
End Function
Why is my post action not populating my FormsRespondModel as it should?
因为您的 <input>
和 <textarea>
字段没有 name
属性。因此,当您提交表单时,绝对不会向服务器发送任何内容。
您可以考虑使用 Html.TextBoxFor
和 Html.TeaxAreaFor
等强类型助手来生成正确的输入字段。您还可以查看以下博客 post,其中解释了如果您希望模型绑定与集合一起使用,应如何准确命名输入字段:http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/
因此,例如要生成正确的索引器名称,您可以将 For Each
替换为 For
循环:
@For i As Integer = 0 To Model.form.fields.Count -1 Step 1
If Model.form.fields(i).fieldTypeId = "text" Then
@<li>
<h4>@Html.DisplayFor(Function(x)x.form.fields(i).title)</h4>
<em>@Html.DisplayFor(Function(x)x.form.fields(i).description)</em>
@Html.TextBoxFor(Function(x)x.form.fields(i).response)
<em>@Html.DisplayFor(Function(x)x.form.fields(i).isRequired)</em>
</li>
End If
If Model.form.fields(i).fieldTypeId = "para" Then
@<li>
<h4>@Html.DisplayFor(Function(x)x.form.fields(i).title)</h4>
<em>@@Html.DisplayFor(Function(x)x.form.fields(i).description)</em>
@Html.TextAreaFor(Function(x)x.form.fields(i).response)
<em>@Html.DisplayFor(Function(x)x.form.fields(i).isRequired)</em>
</li>
End If
Next
显然在这个例子中我们只有 response
属性 的输入字段。因此,当您提交表单时,这将是唯一发送到服务器的东西,也是您视图模型中唯一将被填充的 属性 。如果您想获得其他属性,您可能需要将它们作为隐藏字段包含在表单中(使用 @Html.HiddenFor
帮助器)。话虽如此,与其在表单中生成一堆隐藏字段,不如简单地将一些唯一标识符作为隐藏字段包含在内,这样您就可以使用此操作在 POST 操作中从后端检索这些属性标识符。
每当我从 Respond.vbhtml
页面提交我的表单时,我在控制器中的 Respond_post
函数就会像它应该的那样被调用;但是,FormsRespondModel
中传递的项目是空的。
为什么我的 post 操作没有按预期填充我的 FormsRespondModel?
FormsRespondModel.vb
Public Class FormsRespondModel
Public Property form As cihForm
Public Property lists As cihLists = New cihLists()
Public Property subOrgs As List(Of cihOrganizationSub)
Public Property Events As List(Of cihEvent)
Public Sub New()
End Sub
Public Sub New(formId As String)
form = New cihForm()
form.loadForm(Guid.Parse(formId))
lists.loadOrganizationSubs(ZenCommon.CurrentOrgId, ZenCommon.CurrentUserId)
Dim emptyList() As String = {}
Dim eventsearchList As cihEventSearch = New cihEventSearch(ZenCommon.CurrentOrgId, "", DateTime.Now, ZenCommon.Date2050, True, emptyList, emptyList, emptyList)
Events = eventsearchList.eventList
subOrgs = lists.organizationSubs
End Sub
End Class
Respond.vbhtml
@ModelType CheckImHere.Student.FormsRespondModel
@Using Html.BeginForm()
@html.Hidden(Model.form.formId.ToString())
@For Each fld As Field In Model.form.fields
If fld.fieldTypeId = "text" Then
@<li>
<h4>@fld.title</h4>
<em>@fld.description</em>
<input type="text" placeholder="" value="@fld.response"/>
<em>@fld.isRequired</em>
</li>
End If
If fld.fieldTypeId = "para" Then
@<li>
<h4>@fld.title</h4>
<em>@fld.description</em>
@html.textarea(fld.response)
<em>@fld.isRequired</em>
</li>
End If
Next
<input type="submit" name="cmdSubmit" value="Submit" id="cmdSubmit"/>
End Using
RespondController.vb
<HttpPost>
<ActionName("Respond")>
Function Respond_post(viewModel As FormsRespondModel) As ActionResult
Return View("Respond", viewModel)
End Function
Why is my post action not populating my FormsRespondModel as it should?
因为您的 <input>
和 <textarea>
字段没有 name
属性。因此,当您提交表单时,绝对不会向服务器发送任何内容。
您可以考虑使用 Html.TextBoxFor
和 Html.TeaxAreaFor
等强类型助手来生成正确的输入字段。您还可以查看以下博客 post,其中解释了如果您希望模型绑定与集合一起使用,应如何准确命名输入字段:http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/
因此,例如要生成正确的索引器名称,您可以将 For Each
替换为 For
循环:
@For i As Integer = 0 To Model.form.fields.Count -1 Step 1
If Model.form.fields(i).fieldTypeId = "text" Then
@<li>
<h4>@Html.DisplayFor(Function(x)x.form.fields(i).title)</h4>
<em>@Html.DisplayFor(Function(x)x.form.fields(i).description)</em>
@Html.TextBoxFor(Function(x)x.form.fields(i).response)
<em>@Html.DisplayFor(Function(x)x.form.fields(i).isRequired)</em>
</li>
End If
If Model.form.fields(i).fieldTypeId = "para" Then
@<li>
<h4>@Html.DisplayFor(Function(x)x.form.fields(i).title)</h4>
<em>@@Html.DisplayFor(Function(x)x.form.fields(i).description)</em>
@Html.TextAreaFor(Function(x)x.form.fields(i).response)
<em>@Html.DisplayFor(Function(x)x.form.fields(i).isRequired)</em>
</li>
End If
Next
显然在这个例子中我们只有 response
属性 的输入字段。因此,当您提交表单时,这将是唯一发送到服务器的东西,也是您视图模型中唯一将被填充的 属性 。如果您想获得其他属性,您可能需要将它们作为隐藏字段包含在表单中(使用 @Html.HiddenFor
帮助器)。话虽如此,与其在表单中生成一堆隐藏字段,不如简单地将一些唯一标识符作为隐藏字段包含在内,这样您就可以使用此操作在 POST 操作中从后端检索这些属性标识符。