【问题标题】:MVC: Returning Multiple Rows of data to controllerMVC:向控制器返回多行数据
【发布时间】:2012-04-23 22:52:33
【问题描述】:

我有一个包含几行数据的表,我需要将这些数据返回给控制器。在我看来,我最初通过选择时间段并单击按钮来加载表格。该表加载了我所有的相关记录,但我的一个表单元格包含一个下拉列表。所以我应该能够在下拉菜单中进行选择,点击“更新”,我的控制器会保存更改。

所以在我尝试保存之前一切正常。发送到控制器的模型完全为空。我绑定到表格单元格的列表属性返回到控制器 null。

 @ModelType SuperViewModel
 //We need this a view model in order to store a List of the models in the table   

 @Using (Html.BeginForm())
 @For Each i in Model.CompleteList
    Dim currentItem = i //MVC auto-generated extra declarations. Seems redundant to me but it works.
 @<table>
 <tr>
 <td>@Html.DisplayFor(function(Model)currentItem.Name)</td>
 <td>@Html.DisplayFor(function(Model)currentItem.SampleTime)</td>
 <td>@Html.DropDownListFor(function(Model)currentItem.WorkTime, ViewBag.WorkTimeList)</td>
 </tr>
 Next
 </table>
 <input name="submit" type="submit" value="Update"/>
 End Using

 //Controller
 <HttpPost()>
 function Save(vmodel as SuperViewModel, submit as String) as ActionResult //NOTE: submit parameter is used because we have two submit buttons but its not relevant here
      if submit = "Update"
            db.Entry(vmodel.CompleteList).State = EntityState.Modified//Here the exception is throw because our list is null at this point even tho its tied to the model in the view.
            db.SaveChanges()
      end if
 End Function

注意:这是用 VB.NET 编写的,但欢迎 C# 帮助。我熟悉 MVC 中的两种语言。

【问题讨论】:

  • SuperViewModel 是如何定义的?
  • 其中有几个属性,但适用于此的是“CompleteList”,它是一个列表(另一个模型)。其他模型是由实体框架根据我们的数据库表生成的。
  • End Using 之前是否缺少Next 来关闭For Each?另外,你能添加一些视图呈现的标记吗?

标签: c# asp.net-mvc vb.net razor viewmodel


【解决方案1】:

您需要使用 for 迭代器并让视图使用 HTML 元素的索引元素。我不知道 VB.NET 语法,下面是 c# 示例。这允许模型绑定器正确确定视图模型中的元素,以便它可以在回发时重新填充视图模型。

<table>
 @For(var i = 0; i < Model.CompleteList.Count; i++) 
{
 <tr>
 <td>@Html.DisplayFor(Model.CompleteList[i].Name)</td>
 <td>@Html.DisplayFor(Model.CompleteList[i]..SampleTime)</td>
 <td>@Html.DropDownListFor(Model.CompleteList[i]..WorkTime, ViewBag.WorkTimeList)</td>
 </tr>
}
 </table>

您的 post 方法应该可以正常工作。

【讨论】:

  • 这是正确的。我们没有将行绑定到列表中的特定实例。谢谢。
【解决方案2】:

由于参数名称中的某些冲突,它可能会返回 null(所使用的参数名称也必须在其他地方使用)。试试这个

<input name="subButton" type="submit" value="Update"/>

改变

function Save(vm as SuperViewModel, subButton as String) as ActionResult

【讨论】:

  • 那行不通。 SuperViewModel 在碰到控制器时仍然为空。
  • 参考这篇[博文] (codeblog.shawson.co.uk/…)
  • 那个博客并没有真正的帮助。我添加了 ModelState 验证。如果但视图模型仍然为空,它会通过。
【解决方案3】:

我需要查看DropDownListFor 生成的标记中的名称,但我怀疑这是因为使用currentItem 您绑定的是CompleteList 类型,但您的控制器方法需要完整的@987654324 @ 类型。您显示的代码中没有任何地方显示您绑定到 SuperViewModel 类型。

尝试将您的控制器方法更改为:

<HttpPost()>
 function Save(currentItem as CompleteList, submit as String) as ActionResult //NOTE: submit parameter is used because we have two submit buttons but its not relevant here
      if submit = "Update"
            db.Entry(vmodel).State = EntityState.Modified//Here the exception is throw because our list is null at this point even tho its tied to the model in the view.
            db.SaveChanges()
      end if
 End Function

WorkTime 属性应使用 DropDownList 中的选定值填充。

编辑:更改了参数名称以匹配绑定名称。

【讨论】:

  • 有趣。我不熟悉 VB 版本的模型绑定,但您得到 Nothing(或 null)的原因是模型绑定器无法将值映射到您的控制器参数。在我看来,模型希望映射到名为 currentItem As CompleteList 的东西。
  • 是的,命名很重要。只要可以将它们转换为请求的类型,模型绑定就会尝试映射具有相同名称的事物。
  • 是的,我刚刚注释掉了第二个暗淡并将我所有的 displayfor/hiddenfor 更改为 @Html.HiddenFor(Function(Model) i.SequenceNumber)@Html.DisplayFor(Function(Model) i.SequenceNumber) 没有成功。仍然收到空值(无)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-01
  • 1970-01-01
相关资源
最近更新 更多