【问题标题】:MVC viewmodel is null on post (editing multiple rows)帖子上的 MVC 视图模型为空(编辑多行)
【发布时间】:2015-04-13 16:54:11
【问题描述】:

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

我终于让 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>

【问题讨论】:

  • ASP.NET MVC 不使用“回发”。
  • 您要发布哪些值?尝试使用 for 循环。

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


【解决方案1】:

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

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

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

【讨论】:

  • 好的,但是切换到 List 在我的控制器 GET 中出现错误。如何向 List 类型添加 where 语句?
  • 啊,没关系。我只需要将 .ToList() 添加到末尾。谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-12
相关资源
最近更新 更多