model passed as null to the post method

asp.net-mvc c# entity-framework-6 model-binding

Question

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. 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. 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:


        [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

1
0
12/22/2019 7:34:13 PM

Popular Answer

I believe this is a simple fix. I think what is happening is your SearchId is confusing the 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.

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

I.e. remove model.

Then it should work fine.

0
12/22/2019 4:17:50 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow