ASP.NET MVC 复杂对象 属性 在表单提交时保持为空

ASP.NET MVC Complex Object property stays null on form submit

我正在熟悉 ASP.NET MVC,但我 运行 正在处理一些可能微不足道的事情。我有一个名为 ToDoList 的模型,这是一个包含 ToDoItems 列表的复杂类型:

public class ToDoList
{
    public Guid Id {get;set;}
    public string Name { get; set; }
    
    public virtual ICollection<ToDoItem> Items {get;set;}
}
public class ToDoItem
{
    public int Id { get; set; }
    public string Task { get; set; }
    public bool IsDone { get; set; }

    public virtual ToDoList ToDoList { get; set; }
}

我的详细信息页面如下所示:

@model DataLayer.TomTest.Entities.ToDoList

<h2>@Model.Name</h2>

@using (@Html.BeginForm())
{
    @Html.AntiForgeryToken()
    
    <table>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Items.First().Id)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Items.First().Task)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Items.First().IsDone)
            </th>
        </tr>
        @foreach (var toDoItem in Model.Items)
        {
            <tr>
                <td>
                    @toDoItem.Id
                </td>
                <td>
                    @Html.EditorFor(model => toDoItem.Task)
                </td>
                <td>
                    @Html.EditorFor(model => toDoItem.IsDone, new {htmlAttributes = new {@Style = "margin-left: 10px;"}})
                </td>
            </tr>
        }
    </table>
    
    <input type="submit" value="Save" class="btn btn-default"/>
}

这是它发布到的方法:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Details([Bind(Include = "Id,Name,Items")] ToDoList todoList)
{
    if (ModelState.IsValid)
    {
        _context.Entry(todoList).State = EntityState.Modified;
        await _context.SaveChangesAsync();
        return View();
    }

    return View();
}

如您所见,我在某处阅读时包含了 [Bind] 属性,这将确保我获得正确的属性传递。然而,当我调试它时,只有 Id 属性 被填充,其余的仍然为空。

我该怎么做才能解决这个问题?是视图中的错误吗?还是 Entity Framework 设置不正确? 预先感谢您的帮助。

绑定到列表的模型不适用于 foreach;您需要改用 for 循环。

对于循环中没有编辑器的任何属性,您还需要隐藏输入。

@for (int index = 0; index < Model.Items.Count; index++)
{
    <tr>
        <td>
            @Html.HiddenFor(m => m.Items[index].Id)
            @Model.Items[index].Id
        </td>
        <td>
            @Html.EditorFor(m => m.Items[index].Task)
        </td>
        <td>
            @Html.EditorFor(m => m.Items[index].IsDone, new { htmlAttributes = new { @Style = "margin-left: 10px;" } })
        </td>
    </tr>
}

ASP.NET Wire Format for Model Binding to Arrays, Lists, Collections, Dictionaries - Scott Hanselman's Blog