我一直在研究MVC 4应用程序,并且在尝试更新ViewModel
中的模型时遇到了问题。
我的ViewModel
(详情如下)包含一个ComplexObjectOne
和一个List<ComplexObjectTwo>
。
我的 GET ActionResult
已成功填充数据库中的ViewModel
,并且所有内容都在View
上正确显示。
尝试将ComplexObjectOne
和List<ComplexObjectTwo>
传递给 POST ActionResult
时遇到问题。
ComplexObject
已正确传递,但我尝试过的所有内容都无法通过List<ComplexObjectTwo>
集合。
我的ComplexModelOne Model
public class Test
{
public int Id {get;set;}
public string Result {get;set;}
public virtual ICollection<TestResult> TestResults {get;set;}
}
我的ComplexModelTwo Model
public class TestResult
{
public int Id {get;set;}
public string Result {get;set;}
public string Comment {get;set;}
public virtual Test Test{get;set;}
}
我的ViewModel
public class TestingViewModel
{
public TestingViewModel()
{
if(TestResults == null)
{
TestResults = new List<TestResult>();
}
}
public Test Test {get;set;}
public IEnumerable<TestResult> TestResults {get;set;}
}
我的编辑()获取 ActionResult
public ActionResult Edit(int id = 0)
{
var viewModel = new TestingViewModel();
Test test = testRepo.GetTestById(id);
var results = test.TestResults;
viewModel.Test = test;
viewModel.TestResults = results;
return View(viewModel);
}
我的编辑()发布 ActionResult
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(TestingViewModel model)
{
// do update - left out for brevity
}
我的Edit.cshtml View
@model Namespace.Models.ViewModels.TestingViewModel
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
@Html.EditorFor(model => model.Test, "TestHeader")
<table>
<tr>
<th>Test</th>
<th>Result</th>
<th>Comment</th>
</tr>
@Html.EditorFor(model => model.TestResults, "TestResults")
</table>
<input type="submit" value="Update"/>
}
在我的View
中,我确实使用了几个EditorTemplates
来显示属性字段。
非常感谢任何帮助,评论或建议。我希望能够在单个页面上完成更新这些实体,而不是在Create()步骤中使用多个页面。
谢谢,
Patrick H.(stpatrck)
答案 0 :(得分:1)
替换:
@Html.EditorFor(model => model.TestResults, "TestResults")
使用:
@Html.EditorFor(model => model.TestResults)
然后将您的EditorTemplates/TestResults.cshtml
编辑器模板重命名为EditorTemplates/TestResult.cshtml
(注意缺少的s
)并在里面替换模型声明:
@model IEnumerable<TestResult>
为:
@model TestResult
现在显然这将导致摆脱您在此编辑器模板中编写的任何for
或foreach
循环,因为现在ASP.NET MVC将自动为集合的每个元素调用模板
例如:
@foreach (var item in Model)
{
@Html.EditorFor(x => item.SomeProperty)
}
将简单地成为:
@Html.EditorFor(x => x.SomeProperty)
现在查看生成的标记,并注意输入字段名称的差异。在你之前:
<input type="text" name="item.SomeProperty" value="foo" />
现在你有:
<input type="text" name="TestResults[0].SomeProperty" value="foo" />
现在,当您将表单提交到POST操作时,默认模型绑定器将能够成功绑定集合,因为现在遵循命名约定。您可以在following blog post
中了解有关此约定的更多信息。
您的对象图中也有循环引用,无法成功序列化和模型绑定。您应该使用视图模型来打破这种循环依赖。