3

我一直在研究 MVC 4 应用程序,并在尝试更新ViewModel.

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

我的GET ActionResult成功地从数据库中填充,ViewModel并且一切都正确显示在我的View.

尝试将ComplexObjectOneand传递List<ComplexObjectTwo>POST ActionResult时遇到问题。

ComplexObject正确传递但我尝试过的所有内容都失败了通过集合List<ComplexObjectTwo>

我的 ComplexModelOneModel

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
}

我的编辑.cshtmlView

@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() 步骤中使用的多个页面。

谢谢,

帕特里克 H. (stpatrck)

4

1 回答 1

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或循环,因为现在 ASP.NET MVC 将自动为集合的每个元素调用模板。foreach

例如:

@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.

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

于 2013-09-11T15:05:29.500 回答