I'm having trouble updating the CheckBoxList values to the CustomerDevice table in my Database on the [HttpPost] Edit Action Method CustomerDeviceController.
Index Action Method for the CustomerDeviceController displays a list of Customers from my Customers table. I have an ActionLink labeled "Edit" that passes the CustId value to the CustomerDeviceController [HttpGet] Edit(int? id) Action Method which then displays all selected DevId values assigned to the CustId to the CheckBoxList, this part works fine.
The problem that I'm having is, If I initially added DevId values (1, 3, 4 and 7) for CustId 1006 and then decide to remove just DevId value 1 it actually removes DevId values (3, 4 and 7) and leaves DevId value 1.
So it seems to add the DevId values that I choose to remove and the DevId values that I want to keep it removes. I have included my Models, ViewModel, Controller and Views. I'm hoping someone can see what I'm doing wrong or need to add to correct the issue.
Models
public class CheckBoxListItem
{
public int ID { get; set; }
public string Display { get; set; }
public bool IsChecked { get; set; }
}
public class Customer
{
public int CustId { get; set; }
public string CustDisplayName { get; set; }
public string CustFirstName { get; set; }
public string CustLastName { get; set; }
public string CustCompanyName { get; set; }
public string CustAddress { get; set; }
public string CustPhoneNumber { get; set; }
public string CustMobileNumber { get; set; }
public string CustEmailAddress { get; set; }
public List<customerdevice> CustomerDevices { get; set; }
}
public class CustomerDevice
{
public int CustId { get; set; }
public int DevId { get; set; }
public Customer Customer { get; set; }
public Device Device { get; set; }
}
public class Device
{
public int DevId { get; set; }
public string DevType { get; set; }
public List<customerdevice> CustomerDevices { get; set; }
}
public class WebFormContext : DbContext
{
public WebFormContext(DbContextOptions<webformcontext> options)
: base(options)
{ }
public DbSet<customer> Customers { get; set; }
public DbSet<state> States { get; set; }
public DbSet<device> Devices { get; set; }
public DbSet<customerdevice> CustomerDevices { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<customer>()
.HasKey(c => c.CustId);
modelBuilder.Entity<customer>()
.Property(c => c.CustDisplayName)
.HasColumnType("varchar(100)")
.HasMaxLength(100)
.IsRequired();
modelBuilder.Entity<customer>()
.Property(c => c.CustFirstName)
.HasColumnType("varchar(50)")
.HasMaxLength(50);
modelBuilder.Entity<customer>()
.Property(c => c.CustLastName)
.HasColumnType("varchar(50)")
.HasMaxLength(50);
modelBuilder.Entity<customer>()
.Property(c => c.CustCompanyName)
.HasColumnType("varchar(50)")
.HasMaxLength(50);
modelBuilder.Entity<customer>()
.Property(c => c.CustAddress)
.HasColumnType("varchar(100)")
.HasMaxLength(100)
.IsRequired();
modelBuilder.Entity<customer>()
.Property(c => c.CustPhoneNumber)
.HasColumnType("varchar(12)")
.HasMaxLength(12);
modelBuilder.Entity<customer>()
.Property(c => c.CustMobileNumber)
.HasColumnType("varchar(12)")
.HasMaxLength(12);
modelBuilder.Entity<customer>()
.Property(c => c.CustEmailAddress)
.HasColumnType("varchar(320)")
.HasMaxLength(320);
modelBuilder.Entity<device>()
.HasKey(d => d.DevId);
modelBuilder.Entity<device>()
.Property(d => d.DevType)
.HasColumnType("varchar(50)")
.HasMaxLength(50)
.IsRequired();
modelBuilder.Entity<customerdevice>()
.HasKey(c => new { c.CustId, c.DevId });
modelBuilder.Entity<customerdevice>()
.HasOne(cd => cd.Customer)
.WithMany(c => c.CustomerDevices)
.HasForeignKey(cd => cd.CustId);
modelBuilder.Entity<customerdevice>()
.HasOne(cd => cd.Device)
.WithMany(d => d.CustomerDevices)
.HasForeignKey(cd => cd.DevId);
}
}
ViewModel
public class CustomerDeviceFormViewModel
{
public int CustId { get; set; }
public string CustDisplayName { get; set; }
public List<checkboxlistitem> Devices { get; set; }
}
CustomerDeviceController
public class CustomerDeviceController : Controller
{
private WebFormContext db;
public CustomerDeviceController(WebFormContext context)
{
db = context;
}
public IActionResult Index()
{
return View(db.Customers.ToList());
}
public ActionResult Create(int? id)
{
if (id == null)
{
return NotFound();
}
var customervm = new CustomerDeviceFormViewModel();
{
Customer customer = db.Customers.SingleOrDefault(c => c.CustId == id);
if (customer == null)
{
return NotFound();
}
customervm.CustId = customer.CustId;
customervm.CustDisplayName = customer.CustDisplayName;
var deviceList = db.Devices.ToList();
var checkBoxListItems = new List<checkboxlistitem>();
foreach (var device in deviceList)
{
checkBoxListItems.Add(new CheckBoxListItem()
{
ID = device.DevId,
Display = device.DevType,
IsChecked = false
});
}
customervm.Devices = checkBoxListItems;
return View(customervm);
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CustomerDeviceFormViewModel vm)
{
if (ModelState.IsValid)
{
foreach (var deviceId in vm.Devices.Where(x => x.IsChecked).Select(x => x.ID))
{
var customerDevices = new CustomerDevice
{
CustId = vm.CustId,
DevId = deviceId
};
db.CustomerDevices.Add(customerDevices);
}
db.SaveChanges();
return RedirectToAction("Index");
}
return View(vm);
}
public ActionResult Edit(int? id)
{
Customer customer = db.Customers.SingleOrDefault(c => c.CustId == id);
if (customer == null)
{
return NotFound();
}
var deviceList = db.Devices.ToList();
IEnumerable<int> selectedDevices = db.CustomerDevices
.Where(x => x.CustId == id).Select(x => x.DevId);
var model = new CustomerDeviceFormViewModel()
{
CustId = customer.CustId,
CustDisplayName = customer.CustDisplayName,
Devices = deviceList.Select(x => new CheckBoxListItem()
{
ID = x.DevId,
Display = x.DevType,
IsChecked = selectedDevices.Contains(x.DevId)
}).ToList()
};
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(CustomerDeviceFormViewModel vmEdit)
{
if (ModelState.IsValid)
{
Customer customer = db.Customers
.Include(c => c.CustomerDevices)
.SingleOrDefault(c => c.CustId == vmEdit.CustId);
if (customer == null)
{
return NotFound();
}
IEnumerable<int> selectedDevices = vmEdit.Devices.Where(x => x.IsChecked).Select(x => x.ID);
foreach (int deviceId in selectedDevices)
{
var customerDevice = customer.CustomerDevices.FirstOrDefault(cd => cd.DevId == deviceId);
if (customerDevice != null)
{
customer.CustomerDevices.Remove(customerDevice);
}
else
{
CustomerDevice custDevice = new CustomerDevice
{
CustId = customer.CustId,
DevId = deviceId
};
customer.CustomerDevices.Add(custDevice);
}
}
db.Customers.Update(customer);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(vmEdit);
}
}
Edit View
@using (Html.BeginForm("Edit", "CustomerDevice"))
{
<div class="form-group">
Please select the Devices to assign
</div>
<div class="form-group">
@Html.EditorFor(x => x.Devices)
</div>
@Html.HiddenFor(c => c.CustId)
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
}
Shared\EditorTemplates\CheckBoxListItems.chtml View
<div class="checkbox">
<label>
@Html.HiddenFor(x => x.ID)
@Html.CheckBoxFor(x => x.IsChecked)
@Html.LabelFor(x => x.IsChecked, Model.Display)
</label>
<br>
</div>
Edit View (Source Code) that shows CheckBoxList Values:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Edit Device(s) to Customer - WebForm</title>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">WebForm</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="/">Home</a></li>
<li><a href="/Customer">Customer</a></li>
<li><a href="/CustomerDevice">Customer Device</a></li>
<li><a href="/Home/Contact">Contact</a></li>
</ul>
</div>
</div>
</div>
<div class="container body-content">
<h2>Edit Device(s) to Customer</h2>
<form action="/CustomerDevice/Edit/1006" method="post"> <div class="form-group">
Please select the Devices to assign to Mary Doe
</div>
<div class="form-group">
<div class="checkbox">
<label>
<input data-val="true" data-val-required="The ID field is required." id="Devices_0__ID" name="Devices[0].ID" type="hidden" value="1" />
<input data-val="true" data-val-required="The IsChecked field is required." id="Devices_0__IsChecked" name="Devices[0].IsChecked" type="checkbox" value="true" />
<label for="Devices_0__IsChecked">Desktop</label>
</label>
<br>
</div><div class="checkbox">
<label>
<input data-val="true" data-val-required="The ID field is required." id="Devices_1__ID" name="Devices[1].ID" type="hidden" value="2" />
<input data-val="true" data-val-required="The IsChecked field is required." id="Devices_1__IsChecked" name="Devices[1].IsChecked" type="checkbox" value="true" />
<label for="Devices_1__IsChecked">Laptop</label>
</label>
<br>
</div><div class="checkbox">
<label>
<input data-val="true" data-val-required="The ID field is required." id="Devices_2__ID" name="Devices[2].ID" type="hidden" value="3" />
<input data-val="true" data-val-required="The IsChecked field is required." id="Devices_2__IsChecked" name="Devices[2].IsChecked" type="checkbox" value="true" />
<label for="Devices_2__IsChecked">Keyboard</label>
</label>
<br>
</div><div class="checkbox">
<label>
<input data-val="true" data-val-required="The ID field is required." id="Devices_3__ID" name="Devices[3].ID" type="hidden" value="4" />
<input data-val="true" data-val-required="The IsChecked field is required." id="Devices_3__IsChecked" name="Devices[3].IsChecked" type="checkbox" value="true" />
<label for="Devices_3__IsChecked">Mouse</label>
</label>
<br>
</div><div class="checkbox">
<label>
<input data-val="true" data-val-required="The ID field is required." id="Devices_4__ID" name="Devices[4].ID" type="hidden" value="5" />
<input data-val="true" data-val-required="The IsChecked field is required." id="Devices_4__IsChecked" name="Devices[4].IsChecked" type="checkbox" value="true" />
<label for="Devices_4__IsChecked">Headset</label>
</label>
<br>
</div><div class="checkbox">
<label>
<input data-val="true" data-val-required="The ID field is required." id="Devices_5__ID" name="Devices[5].ID" type="hidden" value="6" />
<input data-val="true" data-val-required="The IsChecked field is required." id="Devices_5__IsChecked" name="Devices[5].IsChecked" type="checkbox" value="true" />
<label for="Devices_5__IsChecked">iPad</label>
</label>
<br>
</div><div class="checkbox">
<label>
<input data-val="true" data-val-required="The ID field is required." id="Devices_6__ID" name="Devices[6].ID" type="hidden" value="7" />
<input data-val="true" data-val-required="The IsChecked field is required." id="Devices_6__IsChecked" name="Devices[6].IsChecked" type="checkbox" value="true" />
<label for="Devices_6__IsChecked">Power Adapter</label>
</label>
<br>
</div><div class="checkbox">
<label>
<input data-val="true" data-val-required="The ID field is required." id="Devices_7__ID" name="Devices[7].ID" type="hidden" value="8" />
<input data-val="true" data-val-required="The IsChecked field is required." id="Devices_7__IsChecked" name="Devices[7].IsChecked" type="checkbox" value="true" />
<label for="Devices_7__IsChecked">Phone</label>
</label>
<br>
</div>
</div>
<input data-val="true" data-val-required="The CustId field is required." id="CustId" name="CustId" type="hidden" value="1006" /> <div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8OavugUS_IJDuIPr6xpVUkAb3CZQhxvBHON5YMfwP6vLHdCL6yuyiD3HruUggKlQpJ2y76owQYcGwjszMdBzS5_YJxx1D1chcDeI_8RMGmDQW-S6yT0BV4yjVVnJYFJgB65jvQOtIaMn9hY593axunQ" /><input name="Devices[0].IsChecked" type="hidden" value="false" /><input name="Devices[1].IsChecked" type="hidden" value="false" /><input name="Devices[2].IsChecked" type="hidden" value="false" /><input name="Devices[3].IsChecked" type="hidden" value="false" /><input name="Devices[4].IsChecked" type="hidden" value="false" /><input name="Devices[5].IsChecked" type="hidden" value="false" /><input name="Devices[6].IsChecked" type="hidden" value="false" /><input name="Devices[7].IsChecked" type="hidden" value="false" /></form>
<hr>
<p>© 2016 - WebForm</p>
</div>
<script src="/lib/jquery/dist/jquery.js"></script>
<script src="/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="/js/site.js?v=EWaMeWsJBYWmL2g_KkgXZQ5nPe-a3Ichp0LEgzXczKo"></script>
<script src="/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
<!--
<script type="application/json" id="__browserLink_initializationData">
{"requestId":"359eef69ee5348909cbbb8b0835fbb27","requestMappingFromServer":false}
</script>
<script type="text/javascript" src="http://localhost:53061/6ddbe519e8204b1d8cafa73b53ac5a72/browserLink" async="async"></script>
<!--
</body>
</html>
Edit View (Source Code) that shows CheckBoxList Values assigned to CustId 1006:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Edit Device(s) to Customer - WebForm</title>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">WebForm</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="/">Home</a></li>
<li><a href="/Customer">Customer</a></li>
<li><a href="/CustomerDevice">Customer Device</a></li>
<li><a href="/Home/Contact">Contact</a></li>
</ul>
</div>
</div>
</div>
<div class="container body-content">
<h2>Edit Device(s) to Customer</h2>
<form action="/CustomerDevice/Edit/1006" method="post"> <div class="form-group">
Please select the Devices to assign to Mary Doe
</div>
<div class="form-group">
<div class="checkbox">
<label>
<input data-val="true" data-val-required="The ID field is required." id="Devices_0__ID" name="Devices[0].ID" type="hidden" value="1" />
<input checked="checked" data-val="true" data-val-required="The IsChecked field is required." id="Devices_0__IsChecked" name="Devices[0].IsChecked" type="checkbox" value="true" />
<label for="Devices_0__IsChecked">Desktop</label>
</label>
<br>
</div><div class="checkbox">
<label>
<input data-val="true" data-val-required="The ID field is required." id="Devices_1__ID" name="Devices[1].ID" type="hidden" value="2" />
<input data-val="true" data-val-required="The IsChecked field is required." id="Devices_1__IsChecked" name="Devices[1].IsChecked" type="checkbox" value="true" />
<label for="Devices_1__IsChecked">Laptop</label>
</label>
<br>
</div><div class="checkbox">
<label>
<input data-val="true" data-val-required="The ID field is required." id="Devices_2__ID" name="Devices[2].ID" type="hidden" value="3" />
<input checked="checked" data-val="true" data-val-required="The IsChecked field is required." id="Devices_2__IsChecked" name="Devices[2].IsChecked" type="checkbox" value="true" />
<label for="Devices_2__IsChecked">Keyboard</label>
</label>
<br>
</div><div class="checkbox">
<label>
<input data-val="true" data-val-required="The ID field is required." id="Devices_3__ID" name="Devices[3].ID" type="hidden" value="4" />
<input checked="checked" data-val="true" data-val-required="The IsChecked field is required." id="Devices_3__IsChecked" name="Devices[3].IsChecked" type="checkbox" value="true" />
<label for="Devices_3__IsChecked">Mouse</label>
</label>
<br>
</div><div class="checkbox">
<label>
<input data-val="true" data-val-required="The ID field is required." id="Devices_4__ID" name="Devices[4].ID" type="hidden" value="5" />
<input data-val="true" data-val-required="The IsChecked field is required." id="Devices_4__IsChecked" name="Devices[4].IsChecked" type="checkbox" value="true" />
<label for="Devices_4__IsChecked">Headset</label>
</label>
<br>
</div><div class="checkbox">
<label>
<input data-val="true" data-val-required="The ID field is required." id="Devices_5__ID" name="Devices[5].ID" type="hidden" value="6" />
<input data-val="true" data-val-required="The IsChecked field is required." id="Devices_5__IsChecked" name="Devices[5].IsChecked" type="checkbox" value="true" />
<label for="Devices_5__IsChecked">iPad</label>
</label>
<br>
</div><div class="checkbox">
<label>
<input data-val="true" data-val-required="The ID field is required." id="Devices_6__ID" name="Devices[6].ID" type="hidden" value="7" />
<input checked="checked" data-val="true" data-val-required="The IsChecked field is required." id="Devices_6__IsChecked" name="Devices[6].IsChecked" type="checkbox" value="true" />
<label for="Devices_6__IsChecked">Power Adapter</label>
</label>
<br>
</div><div class="checkbox">
<label>
<input data-val="true" data-val-required="The ID field is required." id="Devices_7__ID" name="Devices[7].ID" type="hidden" value="8" />
<input data-val="true" data-val-required="The IsChecked field is required." id="Devices_7__IsChecked" name="Devices[7].IsChecked" type="checkbox" value="true" />
<label for="Devices_7__IsChecked">Phone</label>
</label>
<br>
</div>
</div>
<input data-val="true" data-val-required="The CustId field is required." id="CustId" name="CustId" type="hidden" value="1006" /> <div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8OavugUS_IJDuIPr6xpVUkAPOUb8w4S2Vnz2eyIV8YmkPTHJ_uvBT34rWHhobOnSJn4zwQ2tmIW1Ib3ynRht8S8j8a6WEQP3DCpB15DotmCyxr3fYyTIM_lGrE2sNXqfYfjscGCHOhY-irNE3h5jB9k" /><input name="Devices[0].IsChecked" type="hidden" value="false" /><input name="Devices[1].IsChecked" type="hidden" value="false" /><input name="Devices[2].IsChecked" type="hidden" value="false" /><input name="Devices[3].IsChecked" type="hidden" value="false" /><input name="Devices[4].IsChecked" type="hidden" value="false" /><input name="Devices[5].IsChecked" type="hidden" value="false" /><input name="Devices[6].IsChecked" type="hidden" value="false" /><input name="Devices[7].IsChecked" type="hidden" value="false" /></form>
<hr>
<p>© 2016 - WebForm</p>
</div>
<script src="/lib/jquery/dist/jquery.js"></script>
<script src="/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="/js/site.js?v=EWaMeWsJBYWmL2g_KkgXZQ5nPe-a3Ichp0LEgzXczKo"></script>
<script src="/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
<!--
<script type="application/json" id="__browserLink_initializationData">
{"requestId":"db2020dde36447d49b6a626dad3c3c43","requestMappingFromServer":false}
</script>
<script type="text/javascript" src="http://localhost:53061/6ddbe519e8204b1d8cafa73b53ac5a72/browserLink" async="async"></script>
<!--
</body>
</html>
I'm submitting the CheckBoxList values using a Submit Button.
What I have tried:
I have tried setting breakpoints at various areas in my Edit Post and the values seem to be okay to me. But after I update the values they are incorrect.