Asp.net mvc 复杂类型的模型绑定

Asp.net mvc 复杂类型的模型绑定,asp.net-mvc,razor,model-binding,Asp.net Mvc,Razor,Model Binding,我已经制作了一个测试控制器和视图来测试复杂的绑定,但我似乎无法让它工作 这是我的ViewModel: public class TestViewModel { public SubTest MainTest { get; set; } public List<SubTest> SubTestList { get; set; } } public class SubTest { public string Name { get; set; } pub

我已经制作了一个测试控制器和视图来测试复杂的绑定,但我似乎无法让它工作

这是我的ViewModel:

public class TestViewModel
{
    public SubTest MainTest { get; set; }

    public List<SubTest> SubTestList { get; set; }
}

public class SubTest
{
    public string Name { get; set; }
    public int Id { get; set; }
}
公共类TestViewModel
{
公共子测试MainTest{get;set;}
公共列表子测试列表{get;set;}
}
公共类子测验
{
公共字符串名称{get;set;}
公共int Id{get;set;}
}
以下是我的看法:

@model TestViewModel    

@{
    using (Html.BeginForm())
    {
        <h2>Main</h2>

        <p>
            @Html.DisplayTextFor(m => m.MainTest.Id)
            =>
            @Html.DisplayTextFor(m => m.MainTest.Name)
        </p>

        <h2>Subs</h2>

        foreach (var sub in Model.SubTestList)
        {
            <p>
                @Html.DisplayTextFor(m => sub.Id)
                =>
                @Html.DisplayTextFor(m => sub.Name)
            </p>
        }

        <button type="submit">Submit</button>
    }
}
@model TestViewModel
@{
使用(Html.BeginForm())
{
主要

@DisplayTextFor(m=>m.MainTest.Id)
=>
@DisplayTextFor(m=>m.MainTest.Name)

潜艇 foreach(Model.SubTestList中的var sub) { @DisplayTextFor(m=>sub.Id) => @DisplayTextFor(m=>sub.Name)

} 提交 } }
这是我的控制器:

public ActionResult Test()
{
    TestViewModel tvm = new TestViewModel();
    tvm.MainTest = new SubTest() { Id = 0, Name = "Main Test" };

    tvm.SubTestList = new List<SubTest>()
    {
        new SubTest() { Id = 1, Name = "Sub Test 1" } ,
        new SubTest() { Id = 2, Name = "Sub Test 2" } ,
        new SubTest() { Id = 3, Name = "Sub Test 3" } ,
        new SubTest() { Id = 4, Name = "Sub Test 4" } ,
    };

    return View(tvm);
}

[HttpPost]
public ActionResult Test(TestViewModel tvm)
{
    return View(tvm);
}
公共操作结果测试()
{
TestViewModel tvm=新的TestViewModel();
tvm.MainTest=newsubtest(){Id=0,Name=“Main Test”};
tvm.SubTestList=新列表()
{
new SubTest(){Id=1,Name=“Sub Test 1”},
new SubTest(){Id=2,Name=“Sub Test 2”},
new SubTest(){Id=3,Name=“Sub Test 3”},
new SubTest(){Id=4,Name=“Sub Test 4”},
};
返回视图(tvm);
}
[HttpPost]
公共行动结果测试(TestViewModel tvm)
{
返回视图(tvm);
}
加载页面时,所有内容都正确显示,但如果在POST方法中设置断点,则会看到参数值都为null


我做错了什么?

首先
DisplayTextFor()
不生成表单控件(输入、文本区域、选择),因此表单没有可回发的内容

其次,如果确实要编辑模型的值(例如使用文本框),则需要使用
for
循环(或自定义
编辑或模板
for typeof
SubTest
),而不是
foreach
循环作为集合属性

for (int i = 0; i < Model.SubTestList.Count; i++)
{
  @Html.TextBoxFor(m => m.SubTestList[i].Id)
  @Html.TextBoxFor(m => m.SubTestList[i].Name)
}
在主要观点中

@model TestViewModel 
....
@Html.EditorFor(m => m.SubTestList)

EditorFor()
方法接受
IEnumerable
,并且足够智能,可以从模板中为集合中的每个项目呈现html。

没错,我做了更改,它工作正常,非常感谢!。你能解释一下为什么foreach在这种情况下不工作吗?
foreach
循环将生成重复的
name
属性,这些属性与模型属性没有关系(例如
name=“sub.Id”
),并且没有绑定到集合所需的索引器(它还生成重复的
id
属性,这是无效的html)。建议您检查在这两种情况下生成的html以查看差异(它需要是
name=“SubTestList[0].id”
name=“SubTestList[1].id”
等)
@model TestViewModel 
....
@Html.EditorFor(m => m.SubTestList)