post 上的 MVC viewmodel 为空(编辑多行)

MVC viewmodel is null on post (editing multiple rows)

我是 ASP.NET MVC 的新手,几个小时以来一直在寻找这个问题的解决方案。我正在尝试创建一个管理员可以进入并批准注册用户请求并将它们分配给用户组的站点。我从多个 table 获取数据,所以我创建了一个视图模型。

我终于有了 GET Edit 控制器来显示数据,但无法弄清楚 POST Edit 应该如何工作。当我调试时,我意识到我尝试 return 的视图模型只有空值。

我不确定这段代码是有很多问题还是只有一个。在回发时,我需要更新 Access table 中的一些值。如果您需要我提供更多信息,请告诉我。谢谢!

ViewModel:

using System.Collections.Generic;
using AccessRequests.Models;
using System.ComponentModel.DataAnnotations;

namespace AccessRequests.ViewModels
{
    public class UserAccessData
    {
        public IEnumerable<User> Users { get; set; }
        public IEnumerable<Access> Accesses { get; set; }
        public IEnumerable<UserGroup> UserGroups { get; set; }
    }
}

控制器:

// GET: Accesses/Edit/5
public ActionResult Edit(string brand, string group)
{
    var viewModel = new UserAccessData();

    viewModel.Users = db.Users
        .Include(i => i.Accesses)
        .OrderBy(i => i.UserName);

    viewModel.UserGroups = db.UserGroups
        .Where(i => i.Groups.Contains(group));

    if (brand != null)
    {
        viewModel.Accesses = db.Accesses
            .Include(x => x.User)
            .Where(x => x.Brand.ToUpper() == brand);
    }

    return View(viewModel);
}

// POST: Accesses/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Access access, UserAccessData editaccess)
{
    //code here
}

查看:

@model AccessRequests.ViewModels.UserAccessData

@{
    ViewBag.Title = "Edit";
}

<h2>Edit Access</h2>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">

        <table class="table">
            <thead>
                <tr>
                    <th>First Name</th>
                    <th>Last Name</th>
                    <th>Email</th>
                    <th>Company</th>
                    <th>Role</th>
                    <th>Region</th>
                    <th>User Group</th>
                    <th>Approve</th>
                    <th>Deny Reason</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var item in Model.Accesses)
                {
                    @Html.HiddenFor(modelItem => item.UserName)
                    <tr>
                        <td>
                            @Html.DisplayFor(modelItem => item.User.FirstName)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.User.LastName)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.User.Email)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.User.Company)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.User.Role)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.User.Region)
                        </td>
                        <td>
                            @Html.DropDownListFor(m => m.UserGroups, new SelectList(Model.UserGroups, "Groups", "GroupDescription"), "Please select a User Group")
                        </td>
                        <td>
                            @Html.DropDownListFor(modelItem => item.Approved, new SelectList(
                              new List<Object>{
                                   new { value = 0 , text = ""  },
                                   new { value = "YES" , text = "YES" },
                                   new { value = "NO" , text = "NO"}
                                },"value","text", 2))
                        </td>
                        <td>
                            @Html.EditorFor(modelItem => item.DenyReason, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(modelItem => item.DenyReason, "", new { @class = "text-danger" })
                        </td>
                    </tr>
                }
            </tbody>
        </table>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

为了 post 到集合 属性,您的字段名称需要采用类似以下的形式:Accesses[0].ApprovedAccesses[1].Approved 等。在为了实现这一点,您需要使用 for 循环而不是 foreach。您还需要将 属性 的类型从 IEnumerable<Access> 更改为 List<Access>

@for (var i = 0; i < Model.Accesses.Count(); i++)
{
    ...
    @Html.DropDownListFor(m => Model.Accesses[i].Approved, ...)
}

此外,请记住,只有那些具有参与 post 的实际 HTML 字段的属性才会在您的 post 操作中具有值。其他所有内容要么为空,要么为 属性 可能具有的任何默认值。如果您保存的实体具有因未 posted 而被取消的属性,您将覆盖数据库中的这些属性。您需要注意确保所有必要的数据都在 post 中,或者在尝试保存任何内容之前从数据库中重新填充所述数据。