2012-04-23 34 views
2

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

所以一切正常,直到我尝试并保存。发送给控制器的模型是完全无效的。我绑定到表格单元格的列表属性返回给控制器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中熟悉这两种语言。

+0

SuperViewModel是如何定义的? – 2012-04-23 23:03:18

+0

它有几个属性,但在这里适用的是“CompleteList”,它是一个List(Of AnotherModel)。实体框架基于我们的数据库表生成的那个其他模型。 – ExceptionLimeCat 2012-04-23 23:08:26

+0

在“End Using”关闭“For Each”之前是否存在'Next'?另外,你可以添加一些由视图呈现的标记吗? – 2012-04-23 23:33:26

回答

2

您需要使用for iterator并让视图使用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> 

您的文章方法应该工作得很好。

+0

这是正确的。我们没有将我们的行绑定到我们列表中的特定实例。谢谢。 – ExceptionLimeCat 2012-04-26 19:05:31

0

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

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

,改变

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

那没用。 SuperViewModel在击中控制器时仍为空。 – ExceptionLimeCat 2012-04-23 23:30:10

+0

参考这[博客文章](http://codeblog.shawson.co.uk/mvc-strongly-typed-view-returns-a-null-model-on-post-back/) – 2012-04-23 23:31:03

+0

该博客没有真的有帮助。我添加了ModelState验证。它通过,如果但视图模型仍然为空。 – ExceptionLimeCat 2012-04-23 23:46:24

0

我需要看到由DropDownListFor生成的标记名称,但我怀疑这是因为currentItem你对CompleteList一种类型的结合,但您的控制器方法期待完整的SuperViewModel类型。您所显示的代码中没有任何地方显示我看到您绑定到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中选定的值来填充。

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

+0

这是下拉列表的标记。你是说'For Each'下面的第二个声明导致MVC无法识别对模型的绑定? – ExceptionLimeCat 2012-04-24 00:05:58

+0

有趣。我不熟悉的模型结合的VB版本,但你得到什么(或空)的原因是因为模型绑定无法将值映射到控制器参数。它看起来像模型期望映射到名为'currentItem As CompleteList'的东西。 – mgnoonan 2012-04-24 00:06:36

相关问题