在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模型中得到子列表对象的null,我需要在同一个视图上编辑这些项,在formcollection对象中它也是null,有人可以帮我吗?
答案 0 :(得分: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; }
答案 1 :(得分:1)
Erika - 我能够通过使用for循环
来完成这项工作for (int i = 0; i < Model.MyList.Count(); i++) {
@Html.TextboxFor(m => m.MyList[i].someproperty)
}
然而,我更喜欢Darin的解决方案。
另外,我发现如果设置帮助程序的Name属性
,绑定将不起作用答案 2 :(得分:1)
Darin的答案是正确的,但有一点需要注意:您需要在模型中为每个“set”字段添加一个字段,否则它不匹配,结果List of model为null。 / p>
对于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列表将包含所有成员(以及复选框的更新值)。