在单个视图 (MVC4) 上更新模型和模型集合

本文关键字:模型 更新 集合 单个 视图 MVC4 | 更新日期: 2023-09-27 18:30:53

我一直在开发MVC 4应用程序,但在尝试更新ViewModel中的模型时遇到了问题。

我的ViewModel(详见下文)包含一个ComplexObjectOne和一个List<ComplexObjectTwo>

我的 GET ActionResult成功地从数据库中填充了ViewModel,并且所有内容都正确显示在我的View上。

尝试将ComplexObjectOneList<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() 步骤中采用的多个页面。

谢谢

帕特里克·

在单个视图 (MVC4) 上更新模型和模型集合

替换:

@Html.EditorFor(model => model.TestResults, "TestResults")

跟:

@Html.EditorFor(model => model.TestResults)

然后将EditorTemplates/TestResults.cshtml编辑器模板重命名为 EditorTemplates/TestResult.cshtml(请注意缺少的s),并在内部替换模型声明:

@model IEnumerable<TestResult>

自:

@model TestResult

现在显然,这将导致摆脱您可能在此编辑器模板中编写的任何forforeach循环,因为现在 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中阅读有关此约定的更多信息。

此外,对象图中还有循环引用,无法成功序列化和绑定模型。您应该使用视图模型来打破这种循环依赖关系。