skip to Main Content

Html form in Visual Studio Code with multi selectable checkboxes :

<form name="CarServ" id="myForm">
            <div>
                <label>CarModel:</label>
                <input type="text" id="model" size="65" name="CarModel" placeholder="Enter Car Model" required>
            </div>

            <div class="check">
    
                <label>Addons:</label>
    
                <input type="checkbox" name ="SelectedCheckboxes[]" value="10%off First service visit" id="10%off First service visit">
                <label for="10%off First service visit">10%off First service visit</label>
                <input type="checkbox" name="SelectedCheckboxes[]" value="10%off Waterwash"  id="10%off Waterwash">
                <label for="10%off Waterwash">10%off Waterwash</label>


                <input type="checkbox" name ="SelectedCheckboxes[]" value="Free AC Inspection" id="Free AC Inspection">
                <label for="Free AC Inspection">Free AC Inspection</label>


            </div>  
                    
            <button id="btn" type="submit">Submit</button>
        
    
        </form>

Three Models in dotnet core api,
CarForm.cs:

public class CarForm
    {
        public int Id { get; set; }
        [Required]
        public string CarModel { get; set; }
        [Required]
        public string SelectedCheckboxes { get; set; }
        public IList<Selection> Selections { get; set; }


    }

Addon.cs :

public class Addon
    {
        public int Id { get; set; }
        public string CheckboxName { get; set; }
        public IList<Selection> Selections { get; set; }
    }

Selection.cs :

 public class Selection
    {
        public int CarFormId { get; set; }
        public CarForm CarForms { get; set; }

        public Addon Addons { get; set; }
        public int AddonId { get; set; }

    }

CarDbContext.cs :

    public class CarDbContext : DbContext
    {
        public CarDbContext(DbContextOptions<CarDbContext> options) : base(options)
        {
        }

        public DbSet<CarForm> CarForms { get; set; }
        public DbSet<Addon> Addons { get; set; }
        public DbSet<Selection> Selections { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Selection>()
                .HasKey(s => new { s.CarFormId, s.AddonId });

            modelBuilder.Entity<Addon>().HasData(
                new Addon { Id = 1, CheckboxName = "10%off First service visit" },
                new Addon { Id = 2, CheckboxName = "10%off Waterwash" },
                new Addon { Id = 3, CheckboxName = "Free AC Inspection" });
        } 
    }

Created a Controller class:

namespace CarServiceFormApi.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class CarServiceFormController : ControllerBase
    {
        private readonly CarDbContext _context;

        public CarServiceFormController(CarDbContext context)
        {
            _context = context;
        }

        [HttpPost("submit-form")]
        public IActionResult SubmitForm([FromBody] CarForm carForm)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            // Save the CarForm to the database
            _context.CarForms.Add(carForm);
            _context.SaveChanges();

            // Create the selections for the CarForm
            var selections = carForm.SelectedCheckboxes.Select(id => new Selection
            {
                CarFormId = carForm.Id,
                AddonId = id
            });
            _context.Selections.AddRange(selections);
            _context.SaveChanges();

            return Ok();
        }
       
                [HttpGet("get-form-data/{id}")]
                public async Task<IActionResult> GetFormData(int id)
                {
                    // Retrieve the CarForm from the database
                    var carForm = await _context.CarForms.Include(cf => cf.Selections).ThenInclude(s => s.Addons).FirstOrDefaultAsync(cf => cf.Id == id);
                    if (carForm == null)
                    {
                        return NotFound();
                    }

                    // Return the CarForm as JSON
                    return Ok(carForm);
                }
       
    }
}

Basically What I’m trying to achieve is, My html form input details has to be posted to API and stored in the database. Then, with GET method I’m trying to retrieve the data back to the console on success. Since its a multi selectable checkbox, I’m passing an array of Selectedcheckboxes to API and trying to store it in the database.

Now when I run my html form I get a error on the console like

{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":400,"traceId":"00-d0f3aa9cab0ad5f1450f6bbb403a1a9c-adf3f2910efaeafb-00","errors":{"CarModel":["The CarModel field is required."],"Selections":["The Selections field is required."],"SelectedCheckboxes":["The SelectedCheckboxes field is required."]}}

It shows like the "Selections" field is required! but I haven’t declared a Selection field in "CarForm.cs". I hope the line with selection on my "CarForm.cs" is to perform the function of linking models.Couldn’t figure out where did I go wrong in the code.

2

Answers


  1. Try changing SelectedCheckboxes[] to simply SelectedCheckboxes. You are trying to bind a list when it is really a single string value in the backend. The Selections field has a cyclical dependency with CarForm. It is best to create a separate view model that is not tightly coupled to your DTO database relationships.

    Login or Signup to reply.
  2. Basically What I’m trying to achieve is, My html form input details
    has to be posted to API and stored in the database. Then, with GET
    method I’m trying to retrieve the data back to the console on success

    Based on your description and scenario your code snippet does seems logical even if I don’t consider its smell still you are making the simple stuff noisy and clumsy too.

    In order to implement API and HTML stuff javascript might have been the ideal option however, it can either be achived without that even can be possible on general MVC controller.

    Apart from this, I think your model design is also uncessary because all we need a addon list and car details nothing else but why you are using that relational design not clear.

    Let’s move in action how we can do your scenario in clener way:

    Using Web API Controller:

    Model:

    As said earlier all I need is car mdoel along with Addons. Therefore, I am modifying all those as CarFormViewModel.

    public class Addon
        {
            public int Id { get; set; }
            public string? CheckboxName { get; set; }
            public bool IsChecked { get; set; }
        }
    
        public class CarFormViewModel
        {
            public int Id { get; set; }
            public string? CarModel { get; set; }
            public List<Addon>? Addons { get; set; }
        }
    

    Web API Controller:

    [HttpPost("Create")]
    public IActionResult Create([FromBody] CarFormViewModel carFormViewModel)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }
    
        //Get Car Details
        var carDetails = carFormViewModel.CarModel;
    
        //Get Addons Details
        var selectedAddonsValueFromView = carFormViewModel.Addons;
    
        //Do whatever you want to do in database
    
    
    
        return Ok(carFormViewModel);
    
    }
    

    View:

    <div>
        <label>CarModel:</label>
        <input type="text" id="CarModel" class="form-control" name="CarModel" placeholder="Enter Car Model" required>
    </div>
    <hr />
    <div class="check">
    
        <label>Addons:</label>
    
        <input type="checkbox" name="SelectedCheckboxes" value="10%off First service visit">
        <label for="10%off First service visit">10%off First service visit</label>
        <input type="checkbox" name="SelectedCheckboxes" value="10%off Waterwash">
        <label for="10%off Waterwash">10%off Waterwash</label>
        <input type="checkbox" name="SelectedCheckboxes" value="Free AC Inspection">
        <label for="Free AC Inspection">Free AC Inspection</label>
    
    
    </div>
    <hr />
    <button id="btnSubmit" type="submit" class="btn btn-primary" onclick="SubmitToAPI()">
        Submit
    </button>
    

    Script:

    @section scripts {
        <script>
            function SubmitToAPI() {
               
                var addonsList = [];
                //Getting Addons
    
                var addons = document.querySelectorAll('input[type=checkbox]:checked');
    
                for (var i = 0; i < addons.length; i++) {
                    var objAddons = {};
                    objAddons.CheckboxName = addons[i].value;
                    objAddons.IsChecked = true;
                    addonsList.push(objAddons)
                }
    
               
                //Getting Car textbox value
                var CarModel = document.getElementById("CarModel").value;
    
                //Binding API Model
                var objCar = {};
                objCar.CarModel = CarModel;
                objCar.Addons = addonsList;
    
                console.log(objCar);
    
                $.ajax({
                    type: "POST",
                    url: "/api/CarServiceForm/Create",
                    data: JSON.stringify(objCar),
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    success: function (response) {
                        console.log(response);
                    },
                    failure: function (response) {
                        //failure  message
                    }
                });
               
            }
        </script>
    }
    

    Get Response In Console:

    enter image description here

    Output:

    enter image description here

    Note: If you would like to know how you can achieve that using javascript you could check our official document here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search