模型作为 null 传递给 post 方法

model passed as null to the post method

首先,我尝试了网上搜索后遇到的所有解决方案,但没有任何效果。我的想法是按用户 ID 搜索,结果是权限和部门的两个复选框列表。默认情况下,如果用户有权访问该复选框,则会在表中选中该复选框。问题是从视图传递到 post 方法的模型为空。因此,如果我尝试 select 或更改任何内容并单击保存,则该模型没有来自 post 的任何值。我究竟做错了什么?我该如何更正它?

我的视图模型:


    public class MainViewModel
    {        
        public int SearchId { get; set; }
        public List<UserPermissionViewModel> UserPermissions { get; set; }
        public List<UserDepartmentViewModel> UserDepartments { get; set; }
    }

    public class UserDepartmentViewModel
    {
        public int DepId { get; set; }
        public string DepName { get; set; }
        public bool IsChecked { get; set; }
    }

    public class UserPermissionViewModel
    {
        public int PerId { get; set; }
        public string PerName { get; set; }
        public bool IsChecked_ { get; set; }
    }

我的 post 控制器方法:


        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult SaveData (MainViewModel model)
        {
            //remove existing user from the table in db
            db.TBL_UserPermissions
            .RemoveRange(db.TBL_UserPermissions
            .Where(x => x.UserID == model.SearchId));

            db.TBL_User_Dep_Access
              .RemoveRange(db.TBL_User_Dep_Access
              .Where(x => x.UserID == model.SearchId));

            //adding what is selected from the checkboxes to the table in the db
            foreach (var dep in model.UserDepartments)
            {
                if (dep.IsChecked)
                {
                    TBL_User_Dep_Access tBL_User_Dep_ = new TBL_User_Dep_Access();
                    tBL_User_Dep_.UserID = model.SearchId;
                    tBL_User_Dep_.Dep_ID = dep.DepId;
                    tBL_User_Dep_.IsActive = true;
                    db.TBL_User_Dep_Access.Add(tBL_User_Dep_);
                }
            }
            db.SaveChanges();

            //adding what is selected from the checkboxes to the table in the db
            foreach (var per in model.UserPermissions)
            {
                if (per.IsChecked_)
                {
                    TBL_UserPermissions tBL_UserPermissions = new TBL_UserPermissions();
                    tBL_UserPermissions.UserID = model.SearchId;
                    tBL_UserPermissions.PermissionID = per.PerId;
                    tBL_UserPermissions.IsActive = true;
                    db.TBL_UserPermissions.Add(tBL_UserPermissions);
                }
            }
            db.SaveChanges();
            return View();
        }

获取方法:


     public ActionResult Index(int?SearchId)
        {
            var model = new MainViewModel();
            var usr_Dep = db.TBL_User_Dep_Access
              .Where(x => x.UserID == SearchId)
              .Select(x => x.Dep_ID)
              .ToList();

            var usr_Per = db.TBL_UserPermissions
               .Where(x => x.UserID == SearchId)
               .Select(x => x.PermissionID)
               .ToList();

            if (SearchId != null)
            {
                List<UserDepartmentViewModel> Udep 
                        = db.TBL_Department.Select(i =>
                new UserDepartmentViewModel
                {
                    DepId = i.Department_ID,
                    DepName = i.Department_Name,
                    IsChecked = usr_Dep.Contains(i.Department_ID)
                }).ToList();

                List<UserPermissionViewModel> Uper 
                        = db.TBL_Permissions.Select(i =>
                 new UserPermissionViewModel
                {
                    PerId = i.PermissionID,
                    PerName = i.PermissionName,
                    IsChecked_ = usr_Per.Contains(i.PermissionID)

                }).ToList();

                model.UserDepartments = Udep;
                model.UserPermissions = Uper;

            }
            return View(model);
        }

我的观点


@model Staff_Req.Models.MainViewModel

@using (Html.BeginForm("Index", "Access"))
{
    @Html.AntiForgeryToken()
    @Html.TextBox("SearchId", "", new { @id = "SearchId", @placeholder = "Search for...", @class = "form-control" })
    <span class="input-group-btn">
        <input class="btn btn-default" value="Search" type="submit">Go! />
    </span>
}

@using (Html.BeginForm("SaveData", "Access", FormMethod.Post, new { id = "saveForm" }))
{
    @Html.AntiForgeryToken()

    <input type="hidden" name="model.SearchId" id="SaveData_SearchId" />
    <ul>
        @if (Model.UserDepartments != null)
        {
            for (int i = 0; i < Model.UserDepartments.Count(); i++)
            {
                @Html.CheckBoxFor(x => Model.UserDepartments[i].IsChecked)
                @Html.DisplayFor(x => Model.UserDepartments[i].DepName)
                @Html.HiddenFor(x => Model.UserDepartments[i].DepId)
            }
        }

    </ul>
    <ul>
        @if (Model.UserPermissions != null)
        {
            for (int i = 0; i < Model.UserPermissions.Count(); i++)
            {
                @Html.CheckBoxFor(x => Model.UserPermissions[i].IsChecked_)
                @Html.DisplayFor(x => Model.UserPermissions[i].PerName)
                @Html.HiddenFor(x => Model.UserPermissions[i].PerId)
            }
        }

    </ul>

    <input type="submit" value="Save" class="btn btn-default" />
}


@section Scripts {
        <script>
            $("#saveForm").submit(function () {
                $("#SaveData_SearchId").val($("#SearchId").val());
            });
        </script>
    }

感谢任何帮助

您需要使用 [FromBody] 属性修饰 post 数据:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SaveData ([FromBody]MainViewModel model)
{
   ...

我有 运行 你的代码。我看到模型保留了 post 调用中的值。您需要在视图文件中进行以下更改。

@using (Html.BeginForm("SaveData", "Home", FormMethod.Post, new { id = "saveForm" }))
{
    @Html.AntiForgeryToken()

@Html.HiddenFor(m => m.SearchId)
<ul>
    @if (Model?.UserDepartments != null)
    {

        for (int i = 0; i < Model.UserDepartments.Count(); i++)
        {

            @Html.CheckBoxFor(x => x.UserDepartments[i].IsChecked)
            @Html.DisplayFor(x => x.UserDepartments[i].DepName)
            @Html.HiddenFor(x => x.UserDepartments[i].DepId)
        }
    }

</ul>


<ul>
    @if (Model?.UserPermissions != null)
    {

        for (int i = 0; i < Model.UserPermissions.Count(); i++)
        {

            @Html.CheckBoxFor(x => x.UserPermissions[i].IsChecked_)
            @Html.DisplayFor(x => x.UserPermissions[i].PerName)
            @Html.HiddenFor(x => x.UserPermissions[i].PerId)
        }
    }

</ul>


<input type="submit" value="Save" class="btn btn-default" />
}

我相信这是一个简单的修复。我认为正在发生的事情是您的 SearchId 混淆了 modelBinder。

当我复制你的代码时,做了一个 post 并查看了表单数据下的网络选项卡,我看到了这个:

__RequestVerificationToken: T2O4PFE3MRyyVfj1nnnCTV2P6zgGe8-OPFXSvQTeU8fLI07zkQZk1vsKAKf6pzbLl0Df4Cd3VnT3C0XjmLeLWgaRcdXBY6BiXCWQjKjYuqw1
model.SearchId: 1
UserDepartments[0].IsChecked: true
UserDepartments[0].IsChecked: false
UserDepartments[0].DepId: 1
UserDepartments[1].IsChecked: true
UserDepartments[1].IsChecked: false
UserDepartments[1].DepId: 2
UserDepartments[2].IsChecked: false
UserDepartments[2].DepId: 3
UserPermissions[0].IsChecked_: true
UserPermissions[0].IsChecked_: false
UserPermissions[0].PerId: 1
UserPermissions[1].IsChecked_: true
UserPermissions[1].IsChecked_: false
UserPermissions[1].PerId: 2
UserPermissions[2].IsChecked_: false
UserPermissions[2].PerId: 3

看起来这让模型绑定器认为一切都将从模型开始。因为 SearchId 会。

所以要解决你的看法改变

<input type="hidden" name="model.SearchId" id="SaveData_SearchId" />

至此

<input type="hidden" name="SearchId" id="SaveData_SearchId" />

即删除模型。

那么它应该可以正常工作。