简体   繁体   English

模型作为 null 传递给 post 方法

[英]model passed as null to the post method

First of all, I tried all the solutions that I came across after searching online but nothing worked.首先,我尝试了网上搜索后遇到的所有解决方案,但没有任何效果。 My idea is to search by user id and the result is two checkbox lists of permissions and departments.我的想法是按用户 id 搜索,结果是权限和部门的两个复选框列表。 By default, the checkbox is checked in the tables if the user has access to it.默认情况下,如果用户有权访问该复选框,则会在表中选中该复选框。 The problem is the model passed from the view to the post method is null.问题是从视图传递到 post 方法的模型为空。 So if I tried to select or change anything and clicked save, the model doesn't have any values from the post.因此,如果我尝试选择或更改任何内容并单击保存,则该模型没有来自帖子的任何值。 What am I doing wrong?我究竟做错了什么? How do I correct it?我该如何纠正?

my viewmodel:我的视图模型:


    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; }
    }

my post method at controller:我在控制器的 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();
        }

Get method :获取方法:


     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);
        }

my view我的看法


@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>
    }

Appreciate any help感谢任何帮助

You need to decorate your post data with a [FromBody] attribute:您需要使用 [FromBody] 属性装饰您的帖子数据:

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

I have ran your code.我已经运行了你的代码。 And I see model is retaining the values in post call.我看到模型在通话后保留了值。 you need to make below changes in view file.您需要在视图文件中进行以下更改。

@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" />
}

I believe this is a simple fix.我相信这是一个简单的修复。 I think what is happening is your SearchId is confusing the modelBinder.我认为正在发生的事情是您的 SearchId 混淆了 modelBinder。

When I copied your code, did a post and looked at the network tab under form data I saw this:当我复制您的代码,发帖并查看表单数据下的网络选项卡时,我看到了:

__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

It looks like this makes the model binder think everything is going to start with model.看起来这让模型绑定器认为一切都将从模型开始。 because SearchId does.因为 SearchId 确实如此。

So to solve in your view change所以要解决你的看法改变

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

to this对此

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

Ie remove model.即删除模型。

Then it should work fine.那么它应该可以正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM