skip to Main Content

I got this html form with multi selectable checkboxes

            <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 Waterwasht</label>


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


            </div>  

Posting the input values to web API on submit through JavaScript and Created a Model in WEBAPI,

CarForm.cs :

using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;

namespace CarServiceFormApi.Model
{
    public class CarForm
    {
        [key]
        public int Id { get; set; }

        public List<string> SelectedCheckboxes { get; set; }


    }
}

CarDbContext.cs:

using CarServiceFormApi.Model;
using Microsoft.AspNetCore.Cors.Infrastructure;
using Microsoft.EntityFrameworkCore;

namespace CarServiceFormApi.Db
{
    public class CarDbContext : DbContext
    {
        public CarDbContext(DbContextOptions<CarDbContext> options) : base(options)
        {

        }
        public DbSet<CarForm> CarForms { get; set; }
    }
}

CarServiceFormController.cs :

namespace CarServiceFormApi.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class CarServiceFormController : ControllerBase
    {
        private readonly CarDbContext _db;
        private static List<CarForm> CarDataList = new List<CarForm>();


        public CarServiceFormController(CarDbContext db)
        {
            _db = db;
        }

        [HttpPost("submit-form")]
        public IActionResult SubmitForm([FromForm] CarForm formsData)

        {


            // process the form data
 
            List<Selection> selectedCheckboxes = formsData.SelectedCheckboxes;




            // add the data to the database
            var carForm = new CarForm
            {
  
                SelectedCheckboxes= selectedCheckboxes,

            };

            _db.CarForms.Add(carForm);
            _db.SaveChanges();

            CarDataList.Add(carForm);

            return Ok(carForm);
        }
        [HttpGet("get-form-data")]
        public IActionResult GetFormData()

        {
            var data = _db.CarForms.ToList();
            return Ok(data);
        }

    }
}

When I try to "add-migration", to create a row in database , I get an error :

The entity type 'List<string>' requires a primary key to be defined. If you intended to use a keyless entity type, call 'HasNoKey' in 'OnModelCreating'. For more information on keyless entity types

I too got some other simple inputs in my html form and have declared them as "string" in "CarForm.cs", they work fine except my checkboxes, as I post multiple inputs, couldn’t declare them as string. I also tried declaring it as a "[keyless]" attribute but it results in creating columns for all the other inputs except "SelectedCheckboxes".

Can someone tell me what am I doing wrong.

2

Answers


    1. add a connection string
    2. run this command in package manager console (add-migration e.g (add migration "initial migration"))
    3. then after your connection is successful run this command "Update-database"

    your build might fail, and you need to add this in your connection string
    TrustServerCertificate=true;Trusted_Connection=True

    Login or Signup to reply.
  1. Database save “List” using a trick called “one to many” relationship.
    For example if you have:
    car1 : “10%off First service visit” ;”10%off Waterwash”
    car2 : “10%off Waterwash” ; “Free AC Inspection”

    Below shows how database use 2 tables to save the List .
    The first table "carforms" , you will find it doesn’t have a column called "SelectedCheckboxes" but only has an "Id" column. I create 2 value to represent "car1" and "car2".

    enter image description here

    The Second table "Selections" does the trick, it has a column named "CarFormId" , which is a "foreign key" connected to the table "carfroms" key "Id" , so in this table, you can get a information that car1 is related to "10%off First service visit" &"10%off Waterwash" ,car2 is related to "10%off Waterwash" & "Free AC Inspection"
    enter image description here

    More clearly, if you want to change the value of "CarFormId" ,it will only let you choose "1" or "2". Because you only have car1 and car2 in the "carforms" table.
    enter image description here

    This is how the "list" saved in a database using "one to many" trick.
    You will find 2 tables are necessary, so you need to create a "Selection" class.

    public class Selection
        {
            public int SelectionId { get; set; }
            public string SlectionName { get; set; }
        }
    

    And in the "CarForm" class, alternate with the List<Selection> because string couldn’t define a table.

    public class CarForm
        {
            public int Id { get; set; }
    
            public List<Selection> SelectedCheckboxes { get; set; }
        }
    

    And add the "selections" table in the DbContext

    namespace CarServiceFormApi.Db
    {
        public class CarDbContext : DbContext
        {
            public CarDbContext(DbContextOptions<CarDbContext> options) : base(options)
            {
    
            }
            public DbSet<CarForm> CarForms { get; set; }
            public DbSet<Selection> Selections { get; set; }
        }
    }
    

    After doing these. You will be able to update the database successfully. And build to exactly same databse what I showed.

    What I am concerning is that operating with "one to many" relationshop table is not that simple. Visaul studio can generate CURD controller automatically for simple string types but not for list. You will need to learn LINQ. Such as _context.carforms.include(x=>x.selections). This not gonna be easy.
    So I still recommand you to use string if it is enough for you.

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