获取多个复选框值并将它们放入ICollection MVC中

时间:2015-02-16 22:48:44

标签: c# asp.net-mvc model-view-controller web-applications checkbox

我想知道如何检索多个复选框的值。我有一个图表和一些代码,请看一下。我需要做几个步骤:

  1. 将产品/创建文件中的类别表中的所有类别作为复选框(将输入放在产品表中)
  2. 检索所选的复选框
  3. 对于每个选中的复选框,将产品添加到类别表中的自己的列表
  4. 稍后我必须用相应的产品显示每个类别。

    我希望这是有道理的。这是我的代码。如果可能的话,我不想创建另一个文件/模型/视图/控制器。我将所有内容翻译成英文,因此更容易阅读。

    类别模型:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace WebshopMVC.Models
    {
        public class Category
        {
            public int ID { get; set; }
            public string Image { get; set; }
            public string Name { get; set; }
            public string Description{ get; set; }
    
            public virtual ICollection<Product> Producten { get; set; }
        }
    }
    

    产品型号:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace WebshopMVC.Models
    {
        public class Product
        {
            public int ID { get; set; }
            public string Image { get; set; }
            public string Name{ get; set; }
            public string Description{ get; set; }
            public decimal Price{ get; set; }
    
            public virtual ICollection<Category> Categories{ get; set; }
    
            public virtual ICollection<Offer> Offers{ get; set; }
    
        }
    }
    

    产品/创建视图:

    @model WebshopMVC.Models.Categorie
    
        @{
            ViewBag.Title = "Create";
        }
    
        <h2>Create</h2>
    
    
        @using (Html.BeginForm())
        {
        @Html.AntiForgeryToken()
    
        <div class="form-horizontal">
            <h4>Categorie</h4>
            <hr />
            @Html.ValidationSummary(true)
    
            <div class="form-group">
                @Html.LabelFor(model => model.Image, new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.Image)
                    @Html.ValidationMessageFor(model => model.Image)
                </div>
            </div>
    
            <div class="form-group">
                @Html.LabelFor(model => model.Name, new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.Name)
                    @Html.ValidationMessageFor(model => model.Name)
                </div>
            </div>
    
            <div class="form-group">
                @Html.LabelFor(model => model.Description, new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.Description)
                    @Html.ValidationMessageFor(model => model.Description)
                </div>
            </div>
    
    
    
            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <input type="submit" value="Create" class="btn btn-default" />
                </div>
            </div>
        </div>
        }
    
        <div>
            @Html.ActionLink("Back to List", "Index")
        </div>
    

    产品控制器(创建)

        public ActionResult Create()
            {
                return View();
            }
    
            // POST: /Product/Create
            // To protect from overposting attacks, please enable the specific     properties you want to bind to, for 
            // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
            [HttpPost]
            [ValidateAntiForgeryToken]
            public ActionResult Create([Bind(Include =          "ID,Image,Name,Description,Price,Categories")] Product product)
                {
                if (ModelState.IsValid)
                {
                    db.Producten.Add(product);
    
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
    
                return View(product);
            }    
    

    这是一个应该如何的图表:

    Diagram

    这只是一张图片而且是荷兰语,所以我会给你英文翻译:

    Categorie => Category  
    plaatje => Image
    naam => Name
    omschrijving => Description
    
    Product => Product
    plaatje => Image
    naam => Name
    omschrijving => Description
    Prijs => Price
    

    所以,再次:

    1. 让用户创建一个产品并指定一个或多个类别,这些类别将来自“类别表”

    2. 获取所选类别,将其添加到“产品型号”

    3. 中的“类别”列表中
    4. 将产品添加到“类别”模型中的“产品”列表

    5. 稍后我必须能够遍历各个类别并获取他们的产品,因此我可以链接到它们 强文

    6. 步骤2和3可能看起来有点奇怪,但根据模型,一个类别有*产品,一个产品有一个或多个类别,所以我也这样编码

      我一直在努力解决这个问题好几个小时了。如果有人能帮助我,我会非常感激!

      如果您需要任何其他信息,我很乐意给您!

      编辑:
      我在我的项目中添加了一个viewmodel。

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Web;
      
      namespace WebshopMVC.Models
      {
      
          public class ProductCategoryViewModel
          {
              public string Image{ get; set; }
              public string Name { get; set; }
              public string Description{ get; set; }
              public decimal Price { get; set; }
      
              public IEnumerable<Categorie> Categories { get; set; }
      
              public ProductCategoryViewModel()
              {
                  Categories = Categories.ToList();
              }
          }
      }
      

      我还修改了Product / Create.cshtml文件:

      <div class="form-group">
                  @Html.LabelFor(model => Model.Categories)
                  <div class="col-md-10">
                      @foreach (var item in Model.Categories)
                      {
                          <input type="checked" name="Categories" value="@(item.Name)">@(item.Name)
                      }
                  </div>
              </div>
      

      当我尝试进入产品/创建页面时,我现在收到错误:

      对象引用未设置为对象的实例。 (第54行)

      Line 52:             @Html.LabelFor(model => Model.categories)  
      Line 53:             <div class="col-md-10">  
      Line 54:                 @foreach (var item in Model.categories)  
      Line 55:                 {  
      Line 56:                     <input type="checked" name="Categories" value="@(item.Name)">@(item.Name)
      

      我不知道如何修复此错误,我也不明白这是如何工作的。 ProductCategoryViewModel如何从数据库/类别表中检索信息。我没有在任何地方看到任何链接。

      我将添加我的类图,也许这会有所帮助:

      Database Diagram

1 个答案:

答案 0 :(得分:0)

创建ViewModel并将IEnumerable<Categories>放入其中。然后,您可以使用for循环来绑定单个项目的复选框。

public class ProductCategoryViewModel
{
    public string Image{get;set;}
    public string Name{get;set;}
    public string Description{get;set;}
    public double Price{get;set;}

    public IEnumerable<Category> Categories{get;set;}

    public ()
    {
        Categories = Categories.GetAll().ToList();
    }
}

@foreach (var item in Model.Categories) {
    <input type="checked" name="Categories" value="@(item.Name)">@(item.Name)
    //or use html helper which will add hidden input as well
    // @Html.CheckboxFor(x=> x.Name);
}

编辑: - 您需要声明要在cshtml文件顶部的视图中使用的模型:

@model IEnumerable<ProductCategoryViewModel>

然后你需要从控制器动作设置它:

var vm = new ProductCategoryViewModel();
return new View("Create", vm);

这也行不通:

public ProductCategoryViewModel()
{
    Categories = Categories.ToList();
}

Categories尚未填充,因此此声明无用。您需要从某个地方(如数据库)获取类别并设置此属性。像,

public ProductCategoryViewModel()
{
    Categories = <GET FROM DATABASE>;
}