我有一个ASP MVC3项目,它在编辑页面中使用了局部视图。它将正确的值加载到DropDownListFor
中,但是在POST BACK上,项突然为空。
视图使用视图模型来合并一些SQL表。作为该视图模型的一部分,类型为List
的{{1}}集合对象用于存储与特定客户端相关的所有代理Id。为了正确地POST和编辑集合对象中的项,我跟着Steve Sanderson's blog post关于ASP MVC中的变长对象。
此过程适用于代理ID,但是一旦用户点击“保存”,状态代码全部为空。
以下是视图中的代码
BankListAgentId
这是部分
@model Monet.ViewModel.BankListViewModel
@using (Html.BeginForm())
{
<fieldset>
<legend>Stat(s) Fixed</legend>
<table id="fixedRows">
<tr>
<th>State Code</th>
<th>Agent ID</th>
<th></th>
</tr>
@foreach (var item in Model.Fixed)
{
if (!String.IsNullOrWhiteSpace(item.AgentId))
{
@Html.Partial("FixedPartialView", item)
}
}
</table>
<br />
@Html.ActionLink("Add another", "BlankFixedRow", null, null, new { id = "addFixed" })
</fieldset>
}
这是视图模型
@model Monet.Models.BankListAgentId
@using (Html.BeginCollectionItem("Variable"))
{
<tr>
<td>
@Html.DropDownListFor(model => model.StateCode,
(SelectList)ViewBag.StateCodeList, Model.StateCode)
</td>
<td>
@Html.EditorFor(model => model.AgentId)
@Html.ValidationMessageFor(model => model.AgentId)
</td>
<td>
<a href="#" onclick="$(this).parent().remove();" style="float:right;">Delete</a></td>
</tr>
}
以下是来自控制器的编辑页面的原始POST
public class BankListViewModel
{
public int ID { get; set; }
public string BankName { get; set; }
public string LastChangeOperator { get; set; }
public Nullable<System.DateTime> LastChangeDate { get; set; }
public List<BankListAgentId> Fixed { get; set; }
public List<BankListAgentId> Variable { get; set; }
public List<BankListAttachments> Attachments { get; set; }
public BankListViewModel()
{
//Initialize Fixed and Variable stat Lists
Fixed = new List<BankListAgentId>();
Variable = new List<BankListAgentId>();
Models.BankListAgentId agentId = new BankListAgentId();
for (int i = 0; i < 5; i++)
{
Fixed.Add(agentId);
Variable.Add(agentId);
}
//Initialize attachment Lists
Attachments = new List<BankListAttachments>();
Attachments.Add(new BankListAttachments());
}
}
答案 0 :(得分:0)
问题是你正在使用像EditorTemplate这样的Partial视图。部分视图和EditorTemplates是不同的。您可以将局部视图视为服务器端包含一些额外的东西。
所以,这里的问题是你将一个不同的模型传递给部分,而不是在父类中使用。
@foreach (var item in Model.Fixed)
{
if (!String.IsNullOrWhiteSpace(item.AgentId))
{
@Html.Partial("FixedPartialView", item)
}
}
当您提交模型时,部分视图中的帮助程序会将代码呈现为模型是固定的,因此它会错误地格式化并命名部分中的项目。在这种情况下,默认模型绑定器不知道“item”位于名为“Fixed”的集合中,因为您已经通过遍历foreach循环并仅从包含的项目中重新删除了该上下文。
我建议您使用EditorTemplate而不是使用局部视图,因为这是它们设计用来处理(在对象中呈现类型),它们会自动处理集合。
或者,如果您希望渲染部分,则不要传入子模型,只是让它从父级渲染。否则,您将需要做很多工作以确保在部分内部具有正确的命名。
或者,如果您只需要发布此项目集合,那么您可以确保您的发布操作接受IEnumerable<Fixed>
而不是您的父模型。
答案 1 :(得分:0)
您可能希望尝试使用编辑器模板,而不是在循环中注入部分内容。
@foreach (var item in Model.Fixed)
{
if (!String.IsNullOrWhiteSpace(item.AgentId))
{
@Html.EditorFor(item => item, "FixedPartialView")
}
}
然后将FixedPartialView.cshtml放入适当的EditorTemplates文件夹中。我相信,绑定对于框架来说会更加直观。