2011-05-05 71 views
2

在mvc 3 .net FW 4.0项目中,我有一个父子关系相关的数据,我已经建立了我的模型以包含一个列表“孩子”,每个父记录,并显示它下面的例子:Mvc从视图返回空值返回列表<>对象在模型

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/ViewMasterPage.Master" Inherits="System.Web.Mvc.ViewPage<MvcTest.Models.ModelList>" %> 

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> 
    ShowPropReturn 
</asp:Content> 

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 

<h2>ShowPropReturn</h2> 

<script src="<%: Url.Content("~/Scripts/jquery.validate.min.js") %>" type="text/javascript"></script> 
<script src="<%: Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js") %>" type="text/javascript"></script> 

<% using (Html.BeginForm()) { %> 
    <%: Html.ValidationSummary(true) %> 
    <fieldset> 
     <legend>ModelList</legend> 

     <div class="editor-label"> 
      <%: Html.LabelFor(model => model.MyProperty1) %> 
     </div> 
     <div class="editor-field"> 
      <%: Html.EditorFor(model => model.MyProperty1) %> 
      <%: Html.ValidationMessageFor(model => model.MyProperty1) %> 
     </div> 

     <div class="editor-label"> 
      <%: Html.LabelFor(model => model.MyProperty2) %> 
     </div> 
     <div class="editor-field"> 
      <%: Html.EditorFor(model => model.MyProperty2) %> 
      <%: Html.ValidationMessageFor(model => model.MyProperty2) %> 
     </div> 

     <table> 
     <% foreach (var item in Model.MyProperty3) 
      { %> 
       <tr> 
        <td> 
         <%: Html.TextBoxFor(i => item.string1) %> 
        </td> 
        <td> 
         <%: Html.TextBoxFor(i => item.string2) %> 
        </td> 
       </tr> 

     <% } %> 
     </table> 
     <p> 
      <input type="submit" value="Save" /> 
     </p> 
    </fieldset> 
<% } %> 

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

</asp:Content> 

我想通了,如果displayfor仅用来显示一个字段的值,它不会调回这是有道理的。但是我在httppost模型中获得了一个空子对象,我需要在同一个视图上编辑这些项目,它在formcollection对象中也是null,任何人都可以帮我解决这个问题吗?

+0

请参阅[达林的回答](https://stackoverflow.com/questions/5895793/mvc-returning-null-value-back-from-view-for-list-object-in-model/5895839#5895839)for解决方案。但为什么你的方法没有工作?传递给'EditorFor'的lambda需要选择页面/控件的* model类型的属性或字段。它不会在范围内传递一些其他东西:'item'永远不会被传递,所以如何在'EditorFor'的实现中使用它? – Richard 2011-05-05 10:05:54

回答

3

取而代之的是foreach循环的请尝试使用编辑模板:

<table> 
    <%= Html.EditorFor(x => x.MyProperty3) 
</table> 

和相应的编辑器模板中(~/Views/Shared/EditorTemplates/SomeModelType.ascx):

<%@ Control Language="C#" 
    Inherits="System.Web.Mvc.ViewUserControl<AppName.SomeModelType>" 
%> 
<tr> 
    <td> 
     <%= Html.TextBoxFor(x => x.string1) %> 
    </td> 
    <td> 
     <%= Html.TextBoxFor(x => x.string2) %> 
    </td> 
</tr> 

现在,这将产生正确的输入字段名,这样,当您提交的表单值将被正确绑定。

备注:在这种情况下,我认为MyProperty3在你的主视图模型是这样定义(的SomeModelType集合):

public IEnumerable<SomeModelType> MyProperty3 { get; set; } 
+0

非常感谢您的快速回复,完美工作! – Erika 2011-05-05 12:21:50

1

埃里卡 - 我能够通过使用循环

,使这项工作
for (int i = 0; i < Model.MyList.Count(); i++) { 
    @Html.TextboxFor(m => m.MyList[i].someproperty) 
} 

但是,我更喜欢达林的解决方案。

而且我发现,绑定,如果你设置一个辅助的名称属性将无法正常工作

1

Darin的答案是正确的,但有一个警告:你需要有一个字段的形式为每“套”字段,否则它不匹配,并且生成的模型列表为空。

考虑这种情况下AccountModel的列表:

public class AccountModel 
{ 
    public AccountType Type { get; set; } 
    public bool Selected { get; set; } 
    public string Name { get { return Util.GetAccountTypeName(Type); } } 
} 

父视图只需要包含...

@Html.EditorFor(model => model.Accounts) 

...其中...

List<AccountModel> Accounts { get; set; } 

...是整个ViewModel的一部分。现在

,如果您创建编辑模板,像这样...

@model WebLinx.Models.AccountModel 

    <div class="informationRow">   
     @Html.CheckBoxFor(x => x.Selected) 
     <div class="formLabel"> 
      @Html.Label(Model.Name) 
     </div> 
    </div> 

...那么你会得到一个空对象回到你的父模型,当你提交,即使账户与列表显示时复选框视图显示完成。

但是,如果你有一个额外的行:

@model WebLinx.Models.AccountModel 

    <div class="informationRow">   
     @Html.CheckBoxFor(x => x.Selected) 
     @Html.HiddenFor(x=> x.Type) @* extra line with hidden field *@ 
     <div class="formLabel"> 
     @Html.Label(Model.Name) 
     </div> 
    </div> 

,那么你必须在形式和AccountModel对象,AccountModel的列表之间的完全匹配将包含复选框所有成员(和更新的值)。

+0

很好的解释。以这种方式添加所有字段帮助我解决了这个问题。 – Jeroen 2013-10-22 13:34:11