更新 mvc4 中的对象列表 [英] Updating a list of objects in mvc4

查看:27
本文介绍了更新 mvc4 中的对象列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我解决了一个我在 asp.net mvc4 应用程序中遇到的问题并对其进行了简化,因此我可以将其发布在这里.我的基本问题是我试图将项目列表发送到我的视图并编辑任何项目的复选框,然后将列表项目发送回控制器并最终能够保存到数据库.当我将列表发送回控制器时,现在编写代码的方式是作为一个空值出现,就像它从未被实例化一样.

代码如下:

公开课的人属性 ID 作为整数属性名称作为字符串属性 Active As Boolean结束班

在控制器中,我调用了一个名为 BuildPeople 的类,它实际上只是构建要传递的列表的一种方式:

公共类 BuildPeople公共函数 GetPersonList() As List(Of Person)Dim personList As New List(Of Person)personList.Add(GetPerson(1, "Chris", True))personList.Add(GetPerson(2, "Ken", True))personList.Add(GetPerson(3, "Jen", True))返回人员列表结束函数Private Function GetPerson(id As Integer, name As String, active As Boolean) As Person变暗为新人p.ID = idp.Name = 姓名p.Active = 活跃返回 p结束函数结束班

控制器只有编辑能力:

 导入 System.Web.Mvc公共类 PeopleController继承控制器' 获取:/人函数 Index() 作为 ActionResult返回视图()结束函数' 获取:/人/编辑/5函数 Edit() 作为 ActionResultDim bp As New BuildPeople将模型调暗为新列表(人)模型 = bp.GetPersonListViewData.Model = 模型返回视图()结束函数' 发布:/人/编辑/5<HttpPost()>函数 Edit(ByVal listPeople As List(Of Person)) As ActionResult尝试' TODO:在此处添加更新逻辑如果 listPeople Is Nothing Then'不想在这里结束返回视图()别的'想在这里结束Dim i As Integer = listPeople.Count返回视图()万一抓住返回视图()结束尝试结束函数结束班

然后视图如下:

@ModelType List(Of Person)@代码ViewData("Title") = "编辑"布局 = "~/Views/Shared/_Layout.vbhtml"结束代码<h2>编辑</h2>@Using (Html.BeginForm())@Html.AntiForgeryToken()@<div class="form-horizo​​ntal"><h4>人</h4><小时/>@对于模型中的每个项目Dim currentitem = item@Html.HiddenFor(Function(model) currentitem.ID)@Html.EditorFor(Function(model) currentitem.Name)@Html.EditorFor(Function(model) currentitem.Active)下一个<div class="form-group"><div class="col-md-offset-2 col-md-10"><input type="submit" value="Save" class="btn btn-default"/>

结束使用<div>@Html.ActionLink("返回列表", "索引")

解决方案

所以你必须对 HTML 表单的工作原理以及 MVC 模型绑定器的工作原理有一定的了解.

复选框仅在选中后发送回帖子数据中的值.

接下来,只要字段命名遵循正确的命名约定,MVC 中的模型绑定器就会重新构造集合/列表对象.

因此您的循环 For Each item In Model 需要生成具有正确名称的项目.

让我们稍微改变一下你的模型.

公共类 PeopleModel公共财产人作为列表(人)公共属性 SelectedPeople As List(Of Int64) ' 假设 Person.ID 是 Int64结束班

然后像这样更改视图的循环:

Dim itemIndex As Int32 = 0对于每个人作为 Model.People 中的 Person@<input type='checkbox' name='SelectedPeople[@itemIndex]' id='person_@person.ID' value='@person.ID'/>@<input type='hidden' name='SelectedPeople[@itemIndex]' value='-1'/>项目索引 += 1下一个

我们将隐藏元素放在那里,因为它将为未选中的项目提供一个字段值.否则第一个未选中的项目会破坏索引并且模型绑定器将停止.

现在在您的控制器的后处理程序中:

公共函数 ActionName(model As PeopleModel) As ActionResultFor Each id As Int64 In model.SelectedPeople如果 0 

I have taken an issue that I am having with a asp.net mvc4 applications and simplified it so I can post it here. My basic problem is that I am trying to send a list of items to my view and edit the check box of any of the items and then send the list items back to the controller and be able to eventually save to the database. The way the code is written right now when I send the list back to the controller it comes across as a null value just like it was never instantiated.

The code is as follows:

Public Class Person
    Property ID As Integer
    Property Name As String
    Property Active As Boolean
End Class

In the controller I call a class called BuildPeople that is really just a way to build the the list to pass around:

Public Class BuildPeople

    Public Function GetPersonList() As List(Of Person)
        Dim personList As New List(Of Person)
        personList.Add(GetPerson(1, "Chris", True))
        personList.Add(GetPerson(2, "Ken", True))
        personList.Add(GetPerson(3, "Jen", True))
        Return personList
    End Function

    Private Function GetPerson(id As Integer, name As String, active As Boolean) As Person
        Dim p As New Person
        p.ID = id
        p.Name = name
        p.Active = active
        Return p
    End Function  
End Class

The controller only has the edit ability:

    Imports System.Web.Mvc

Public Class PeopleController
    Inherits Controller

    ' GET: /People
    Function Index() As ActionResult
        Return View()
    End Function

    ' GET: /People/Edit/5
    Function Edit() As ActionResult
        Dim bp As New BuildPeople
        Dim model As New List(Of Person)
        model = bp.GetPersonList
        ViewData.Model = model
        Return View()
    End Function

    ' POST: /People/Edit/5
    <HttpPost()>
    Function Edit(ByVal listPeople As List(Of Person)) As ActionResult
        Try
            ' TODO: Add update logic here
            If listPeople Is Nothing Then
                'Don't want to end up here
                Return View()
            Else
                'Want to end up here
                Dim i As Integer = listPeople.Count
                Return View()
            End If
        Catch
            Return View()
        End Try
    End Function
End Class

And then the view is as follows:

@ModelType List(Of Person)
@Code
    ViewData("Title") = "Edit"
    Layout = "~/Views/Shared/_Layout.vbhtml"
End Code

<h2>Edit</h2>

@Using (Html.BeginForm())
    @Html.AntiForgeryToken()

    @<div class="form-horizontal">
        <h4>Person</h4>
        <hr />
        @For Each item In Model
        Dim currentitem = item
            @Html.HiddenFor(Function(model) currentitem.ID)
            @Html.EditorFor(Function(model) currentitem.Name)
            @Html.EditorFor(Function(model) currentitem.Active)
        Next

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
End Using

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

解决方案

So you have to have some understanding of how HTML forms work as well as how the MVC model binder works.

Checkboxes only send a value back in the post data if they are checked.

Next, the model binder in MVC will reconstitute collection/list objects as long as the field naming follows the proper naming convention.

So your loop For Each item In Model needs to produce items with the correct name.

Let's change your model slightly.

Public Class PeopleModel
  Public Property People As List(Of Person)
  Public Property SelectedPeople As List(Of Int64)  ' Assuming Person.ID is Int64
End Class

Then your change your view's loop like so:

Dim itemIndex As Int32 = 0
For Each person As Person In Model.People
  @<input type='checkbox' name='SelectedPeople[@itemIndex]' id='person_@person.ID' value='@person.ID' />
  @<input type='hidden' name='SelectedPeople[@itemIndex]' value='-1' />
  itemIndex += 1
Next

We place the hidden element in there because it will provide a field value for unchecked items. Otherwise the first unchecked item would break the indices and the model binder would stop.

Now in your controller's post handler:

<HttpPost>
Public Function ActionName(model As PeopleModel) As ActionResult

  For Each id As Int64 In model.SelectedPeople
    If 0 < id Then
      ' This is the id of a selected person - do something with it.
    End If
  Next

End Function

这篇关于更新 mvc4 中的对象列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆