4

I feel this may be an easy fix but I cannot seem to get around it. I have an ASP.NET Core web application and I'm using an ajax form to submit data to my controller for processing. The problem I have is that my checkboxes always pass in as "false" even though they may be checked.

I searched for some answers but nothing I've tried has worked. Things like using the checked property, ensuring the name is correct.

Can anyone shed some light on why the values are ignored when the form is submitted to the controller and how I can fix it?

Form

<form asp-action="CreateCustomView" asp-controller="Data"
        data-ajax="true"
        data-ajax-method="POST">
        <div class="row">
            <div class="col">
                <div class="custom-control custom-checkbox">                            
                    <input type="checkbox" class="custom-control-input" id="ColName" name="ColName" checked>
                    <label class="custom-control-label" for="ColName">Name</label>
                </div>
            </div>

            <button type="reset">Reset</button>
            <button type="submit">Save changes</button>
</form>

Model

namespace MyProject.Data
{
    public class GridView : BaseEntity
    {
        public string Name { get; set; }               
        public bool ColName { get; set; }
    }
}

DataController

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MyProject.Data;
using Microsoft.AspNetCore.Mvc;

namespace MyProject.UI.Controllers
{
    public class DataController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }
        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult CreateCustomView(GridView data)
        {
            //This method is incomplete, there is a break at the ActionResult to see what values are passed into `data`.  In production, the values would be handled and the changes would be saved.
            return View();
        }
    }
}

I have a breakpoint on the method CreateCustomView to see what values are passed, no matter what checkboxes I check, they are always being passed as false.

Can anyone help with this rather strange problem?

Update

As per the answer supplied by @Reyan-Chougle, if you're using CORE you need to supply the input as follows:

<input asp-for="@Model.ColType" type="checkbox" />

When the page is rendered, the control is automatically given a hidden field. Here is what the HTML of the above control renders as:

<input type="checkbox" class="custom-control-input" id="ColType" value="true" data-val="true" data-val-required="The ColType field is required." name="ColType">
<input type="hidden" value="false" id="ColType" name="ColType">

As you can see it creates a hidden checkbox with a value of false. This means that, as a boolean type it always has a value of true or false on submission.

Yanayaya
  • 2,044
  • 5
  • 30
  • 67
  • 1
    because unchecked checkboxes do not get posted by the browser. you have to post additional hidden field see https://stackoverflow.com/questions/1809494/post-unchecked-html-checkboxes and https://stackoverflow.com/questions/2697299/asp-net-mvc-why-is-html-checkbox-generating-an-additional-hidden-input – Joe Audette Jul 17 '19 at 15:19
  • Is it possible you're posting them as `application/x-www-form-urlencoded` when the app is expecting `application/json`? – codeMonkey Jul 17 '19 at 15:25
  • Did you find any solution? – Reyan Chougle Jul 22 '19 at 09:17

4 Answers4

8

As you are using ASP.NET Core, it is recommend to use the Tag Helpers:

<div class="form-group">
    <label asp-for="@Model.ColName"></label>
    <input asp-for="@Model.ColName" type="checkbox" />
</div>
Reyan Chougle
  • 4,917
  • 2
  • 30
  • 57
6

If not using asp-for attribute , you can modify your codes to add a hidden field. It will be submitted regardless whether the checkbox is checked or not. If the checkbox is checked, the posted value will be true,false. The model binder will correctly extract true from the value. Otherwise it will be false :

<input type="checkbox" class="custom-control-input" data-val="true" id="ColName" name="ColName" value="true" checked>
<label class="custom-control-label" for="ColName">Name</label>
<input name="ColName" type="hidden" value="false">
Nan Yu
  • 26,101
  • 9
  • 68
  • 148
4

I ran into a similar issue. There is a form we have that contains many fields that include textboxes, select (dropdown) menus, checkboxes and of course labels. All fields save to the database properly EXCEPT for the three checkbox options we have. I just figured out the fix after fooling with it off and on for weeks. I hope this helps someone:

This is what the code used to look like:

$(this).attr('data-val', 'true');

This is what fixed the problem:

$(this).val(true);

Here is the whole function that includes the fix:

$('form').on('change', ':checkbox', function () {
    if (this.checked) {
        $(this).val(true);
    }
    else {
        $(this).val(false);
    }
});

CaptainGenesisX
  • 328
  • 3
  • 10
0

try to use

 @Html.CheckBox("ColName", true)   
Muhammad Dyas Yaskur
  • 6,914
  • 10
  • 48
  • 73