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
your build might fail, and you need to add this in your connection string
TrustServerCertificate=true;Trusted_Connection=True
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".
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"
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.
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.
And in the "CarForm" class, alternate with the
List<Selection>
because string couldn’t define a table.And add the "selections" table in the DbContext
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.