Search code examples
c#asp.net-mvcrazor

HTML helps checkboxfor not passing the data to controller


I have been trying to pass data to the controller from the form but it gives me null values. I have my model/controller and view as below. I even tried to use Form Collection but why is this not binding the data properly?

Role.cs

 public partial class Role
    {
        public int Role_Id { get; set; }
        public int EmpID { get; set; }
        public Nullable<bool> Door_Unlock { get; set; }
        public Nullable<bool> Accounts { get; set; }
        public Nullable<bool> Bounds_Email { get; set; }
        public Nullable<bool> Salary_Privilege { get; set; }
        public Nullable<bool> Card_Acceptance { get; set; }
        public Nullable<bool> IsAdmin { get; set; }

        public virtual Employee Employee { get; set; }
    }

My controller is;

RoleController:

 [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "EmpID,Door_Unlock,Accounts,Bounds_Email,Salary_Privilege,Card_Acceptance,IsAdmin")] Role roles)
        {
 if (ModelState.IsValid)
                {

                    //db.Roles.Add(roles);
                   // db.SaveChanges();
                    return RedirectToAction("Index");
                }

Create.cshtml

@model xxxxx.Models.Role

@{
    ViewBag.Title = "Create";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Create</h2>
@*@using (Html.BeginForm())*@
<form method="POST">


    @Html.AntiForgeryToken()
<div class="form-horizontal">
    <div class="form-group">
        @Html.LabelFor(model => model.Employee.FirstName, "Select Employee", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownList("EnrollNumber", null, "-Select Employee-", htmlAttributes: new { id = "ddEnrollNumber", @class = "form-control" })
            @Html.ValidationMessageFor(model => model.Employee.FirstName, "", new { @class = "text-danger" })

        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Accounts, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.CheckBoxFor( model => model.Accounts.Value, new { name = "accountsCheck", @class = "accountsCheck", @checked = "checked" })
            @Html.ValidationMessageFor(model => model.Accounts, "", new { @class = "text-danger" })

        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Bounds_Email, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.CheckBoxFor(model => model.Bounds_Email.Value, new { @class = "boundsCheck", @checked = "checked" })
            @Html.ValidationMessageFor(model => model.Bounds_Email, "", new { @class = "text-danger" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(model => model.Card_Acceptance, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.CheckBoxFor(model => model.Card_Acceptance.Value, new { @class = "cardCheck", @checked = "checked" })
            @Html.ValidationMessageFor(model => model.Card_Acceptance, "", new { @class = "text-danger" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(model => model.Door_Unlock, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.CheckBoxFor(model => model.Door_Unlock.Value, new { @class = "doorUnlockCheck", @checked = "checked" })
            @Html.ValidationMessageFor(model => model.Door_Unlock, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Salary_Privilege, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.CheckBoxFor(model => model.Salary_Privilege.Value, new { @class = "salaryCheck", @checked = "checked" })
            @Html.ValidationMessageFor(model => model.Salary_Privilege, "", new { @class = "text-danger" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(model => model.IsAdmin, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.CheckBoxFor(model => model.IsAdmin.Value, new { @class = "isAdminCheck", @checked = "checked" })
            @Html.ValidationMessageFor(model => model.IsAdmin, "", new { @class = "text-danger" })
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Grant Permissions" class="btn green" />
        </div>
    </div>
    </div>
</form>


<div>
    <button type="button" class="btn green">  @Html.ActionLink("Back to List", "Index", null, new { @style = "color:#FFFFFF;" }) <span class=""></span></button>

</div>


            return View();


    }

I even tried to use Request.Form[] method but I cannot understand why is this not binding the data properly and passing to the controller? roles in the controller param is always null.


Solution

  • As already mentioned in the comments above, You cannot use CheckBoxFor() on a bool? What I would suggest is to change your model class to;

    public partial class Role
    {
        public int Role_Id { get; set; }
        public int EmpID { get; set; }
        public bool Door_Unlock { get; set; }
        public bool Accounts { get; set; }
        public bool Bounds_Email { get; set; }
        public bool Salary_Privilege { get; set; }
        public bool Card_Acceptance { get; set; }
        public bool IsAdmin { get; set; }
    
        public virtual Employee Employee { get; set; }
    }
    

    and your controller remains the same;

    [HttpPost]
            [ValidateAntiForgeryToken]
            public ActionResult Create([Bind(Include = "EmpID,Door_Unlock,Accounts,Bounds_Email,Salary_Privilege,Card_Acceptance,IsAdmin")] Role roles)
            {
     if (ModelState.IsValid)
                    {
    
                        //db.Roles.Add(roles);
                       // db.SaveChanges();
                        return RedirectToAction("Index");
                    }
    

    and your Create.cshtml;

    @model granjurEPS.Models.Role
    
    @{
        ViewBag.Title = "User Role";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    
    <h2>New User Role</h2>
    @*@using (Html.BeginForm())*@
    <form method="POST">
    
    
        @Html.AntiForgeryToken()
    <div class="form-horizontal">
        <div class="form-group">
            @Html.LabelFor(model => model.Employee.FirstName, "Select Employee", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownList("EnrollNumber", null, "-Select Employee-", htmlAttributes: new { id = "ddEnrollNumber", @class = "form-control" })
    
    
                @Html.ValidationMessageFor(model => model.Employee.FirstName, "", new { @class = "text-danger" })
    
            </div>
        </div>
    
        <div class="form-group">
            @Html.LabelFor(model => model.Accounts, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.CheckBoxFor( model => model.Accounts, new { name = "accountsCheck", @class = "accountsCheck" })
                @*@Html.EditorFor(model => model.Accounts.Value)*@
    
                @Html.ValidationMessageFor(model => model.Accounts, "", new { @class = "text-danger" })
    
            </div>
        </div>
    
        <div class="form-group">
            @Html.LabelFor(model => model.Bounds_Email, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.CheckBoxFor(model => model.Bounds_Email, new { @class = "boundsCheck" })
                @Html.ValidationMessageFor(model => model.Bounds_Email, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            @Html.LabelFor(model => model.Card_Acceptance, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.CheckBoxFor(model => model.Card_Acceptance, new { @class = "cardCheck" })
                @Html.ValidationMessageFor(model => model.Card_Acceptance, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            @Html.LabelFor(model => model.Door_Unlock, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.CheckBoxFor(model => model.Door_Unlock, new { @class = "doorUnlockCheck" })
                @Html.ValidationMessageFor(model => model.Door_Unlock, "", new { @class = "text-danger" })
            </div>
        </div>
    
        <div class="form-group">
            @Html.LabelFor(model => model.Salary_Privilege, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.CheckBoxFor(model => model.Salary_Privilege, new { @class = "salaryCheck" })
                @Html.ValidationMessageFor(model => model.Salary_Privilege, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            @Html.LabelFor(model => model.IsAdmin, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.CheckBoxFor(model => model.IsAdmin, new { @class = "isAdminCheck" })
                @Html.ValidationMessageFor(model => model.IsAdmin, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Grant Permissions" class="btn green" />
            </div>
        </div>
        </div>
    </form>
    
    
    <div>
        <button type="button" class="btn green">  @Html.ActionLink("Back to List", "Index", null, new { @style = "color:#FFFFFF;" }) <span class=""></span></button>
    
    </div>