在单个视图 (MVC4) 上更新模型和模型集合
本文关键字:模型 更新 集合 单个 视图 MVC4 | 更新日期: 2023-09-27 18:30:53
我一直在开发MVC 4应用程序,但在尝试更新ViewModel
中的模型时遇到了问题。
我的ViewModel
(详见下文)包含一个ComplexObjectOne
和一个List<ComplexObjectTwo>
。
我的 GET ActionResult
成功地从数据库中填充了ViewModel
,并且所有内容都正确显示在我的View
上。
尝试将ComplexObjectOne
和List<ComplexObjectTwo>
传递到开机自检ActionResult
时遇到问题。
ComplexObject
正确传递,但我尝试的所有内容都未能通过List<ComplexObjectTwo>
集合。
我的复杂模型一Model
public class Test
{
public int Id {get;set;}
public string Result {get;set;}
public virtual ICollection<TestResult> TestResults {get;set;}
}
我的复杂模型二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
}
My 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() 步骤中采用的多个页面。
谢谢
帕特里克·
替换:
@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
中阅读有关此约定的更多信息。
此外,对象图中还有循环引用,无法成功序列化和绑定模型。您应该使用视图模型来打破这种循环依赖关系。