CheckBoxList更新问题

时间:2016-11-07 16:17:24

标签: c# asp.net-core-mvc entity-framework-core

我正在使用ASP.NET Core MVC,EntityFramework Core和C#。

我无法在[HttpPost]编辑操作方法CustomerDeviceController上将CheckBoxList值更新到我的数据库中的CustomerDevice表。 CustomerDevice表是一个JOIN表,在Customer表和Device表之间具有多对多。

CustomerDeviceController的我的索引操作方法显示来自Customers表的Customers列表。我有一个标记为“编辑”的ActionLink,它将CustId值传递给CustomerDeviceController [HttpGet]编辑(int?id)操作方法,然后显示分配给CustBox的所有选定的DevId值到CheckBoxList,这部分工作正常。

当我尝试更新CheckBoxList值时,它会添加我选择删除的DevId值以及我想要保留它的DevId值。

因此,例如:如果我最初为CustId 1006添加了DevId值(1,3,4和7),然后决定编辑以仅删除DevId值1,它实际上删除了DevId值(3,4和7)并离开DevId值1.

模型

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 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<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<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);
    }
}

视图模型

public class CustomerDeviceFormViewModel
{
    public int CustId { get; set; }
    public string CustDisplayName { get; set; }
    public List<CheckBoxListItem> Devices { get; set; }
}

控制器

public class CustomerDeviceController : Controller
{
    // GET: /<controller>/
    public IActionResult Index()
    {
        return View(db.Customers.ToList());
    }


    public ActionResult Edit(int? id)
    {
        Customer customer = db.Customers.SingleOrDefault(c => c.CustId == id);
        if (customer == null)
        {
            return NotFound();
        }
        // Get all devices
        var deviceList = db.Devices.ToList();
        // Get the selected device ID's for the customer
        IEnumerable<int> selectedDevices = db.CustomerDevices
            .Where(x => x.CustId == id).Select(x => x.DevId);
        // Build view model
        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);

            // Add the new selected devices
            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);
                }
            }

            // Update the customer
            db.Customers.Update(customer); //or just db.Update(customer); same thing
                                           // Save and redirect
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(vmEdit);
    }
}

共享/ EditorTemplates / CheckBoxListItem.chtml

<div class="checkbox">
<label>
    @Html.HiddenFor(x => x.ID)
    @Html.CheckBoxFor(x => x.IsChecked)
    @Html.LabelFor(x => x.IsChecked, Model.Display)
</label>
<br />

修改视图

<div class="form-group">
    Please select the Devices to assign to <b>@Html.DisplayFor(c => c.CustDisplayName)</b>
</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>

0 个答案:

没有答案