Model binding with complex type

陌路散爱 提交于 2019-12-24 04:25:11

问题


I have made a test controller and view to test complex binding, but I can't seem to make it work.

Here is my 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; }
}

Here is my View:

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

And here is my controller:

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);
}

When I load the page, everything displays correctly, but if I set a breakpoint in the POST method, I see that the parameter values are both null.

What am I doing wrong ?


回答1:


Firstly DisplayTextFor() does not generate form controls (input, textarea, select) therefore there is nothing for the form to post back.

Secondly, if you did want to edit the values of your model (say using a textbox), then you would need to use a for loop (or custom EditorTemplate for typeof SubTest) not a foreach loop for your collection property, for example

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

Or using an EditorTemplate (the name of the template must match your model type

In /View/Shared/EditorTemplates/SubTest.cshtml

@model yourAssembly.SubTest
@Html.TextBoxFor(m => m.Id)
@Html.TextBoxFor(m => m.Name)

and in the main view

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

The EditorFor() method accepts IEnumerable<T> and is smart enough to rendered the html from the template for each item in the collection.



来源:https://stackoverflow.com/questions/31954735/model-binding-with-complex-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!