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

时间:2015-04-13 16:54:11

标签: c# asp.net asp.net-mvc entity-framework viewmodel

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

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

我不确定此代码是否存在许多问题,或者只是一个问题。在回发时,我需要更新Access表中的一些值。如果您需要我的更多信息,请告诉我。谢谢!

视图模型:

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>

1 个答案:

答案 0 :(得分:2)

要发布到集合属性,您的字段名称必须采用以下格式: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, ...)
}

另外,请记住,只有具有参与帖子的实际HTML字段的属性才会在后期操作中包含值。其他所有内容都将为null或属性可能具有的任何默认值。如果您保存的实体的属性已被删除,因为它们尚未发布,您将覆盖数据库中的这些属性。您需要注意确保在帖子中发布所有必要的数据,或者在尝试保存任何内容之前从数据库重新填充所述数据。