【问题标题】:Mvc returning null value back from view for list<> object in modelMvc 从视图中返回 null 值,用于模型中的 list<> 对象
【发布时间】:2011-05-05 09:56:18
【问题描述】:

在 mvc 3 .Net FW 4.0 项目中,我有一个与父子关系相关的数据,我建立了我的模型以包含每个父记录的“子”列表,并将其显示为下面的例子:

<%@ 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 对象中也是空的,有人可以帮我吗?

【问题讨论】:

  • 请参阅Darin's answer 了解解决方案。但为什么你的方法不起作用?传递给EditorFor 的 lambda 需要选择页面/控件的 模型类型 的属性或字段。它不会在范围内传递一些其他东西:item 永远不会传递,那么它如何在EditorFor 的实现中使用?

标签: model-view-controller asp.net-mvc-3


【解决方案1】:

尝试使用编辑器模板代替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; }

【讨论】:

    【解决方案2】:

    Erika - 我能够通过使用 for 循环来完成这项工作

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

    不过,我更喜欢达林的解决方案。

    我还发现,如果您设置了帮助程序的 Name 属性,绑定将不起作用

    【讨论】:

      【解决方案3】:

      Darin 的回答是正确的,但有一点需要注意:您需要在表单中为模型中的每个“set”字段设置一个字段,否则它不匹配并且生成的模型列表为空。

      考虑这种情况下的 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 的列表将包含所有成员(以及复选框的更新值)。

      【讨论】:

      • 很好的解释。以这种方式添加所有字段帮助我解决了问题。
      猜你喜欢
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多