2015-07-27 2 views
0

Я использую Entity Framework, и у меня есть много-много отношений между Продуктами и Категориими. Я создал свои модели, и они, похоже, правильно создали таблицы. Теперь я пытаюсь вставить продукт, и я получаю ошибку: «Значение не может быть нулевым». на линии: @Html.ListBoxFor(model => model.ProductCategories, Model.CategorySelectList.Select(c => new SelectListItem { Text = c.Text, Value = c.Value }), new { @class = "chzn-select", data_placeholder = "Choose categorie(s)..."})html listboxfor value не может быть null

Вот мой ProductModel:

public class ProductModel 
{ 
    public int ID { get; set; } 

    [Required(ErrorMessage = "Required")] 
    [Index("ItemNumber", 1, IsUnique = true)] 
    [Display(Name = "Item #")] 
    public int itemNumber { get; set; } 

    [Required(ErrorMessage = "Required")] 
    [Display(Name = "Product")] 
    [MaxLength(50)] 
    public String product { get; set; } 

    [Display(Name = "Description")] 
    [MaxLength(500)] 
    public String description { get; set; } 

    [DefaultValue(true)] 
    [Display(Name = "Active?")] 
    public bool active { get; set; } 

    [Display(Name = "Image Name")] 
    public String imageName { get; set; } 

    [Display(Name = "PDF Name")] 
    public String PDFName { get; set; } 

    [Display(Name = "Category(s)")] 
    public virtual ICollection<CategoryModel> ProductCategories { get; set; } 

    public IEnumerable<SelectListItem> CategorySelectList { get; set; } 

    //public ICollection<CategoryModel> CategoryList { get; set; } 

    public virtual BrochureModel Brochure { get; set; } 

    public IEnumerable<SelectListItem> BrochureList { get; set; } 

    public static IEnumerable<SelectListItem> getCategories(int id = 0) 
    { 
     using (var db = new ProductContext()) 
     { 
      List<SelectListItem> list = new List<SelectListItem>(); 
      var categories = db.Categories.ToList(); 
      foreach (var cat in categories) 
      { 
       SelectListItem sli = new SelectListItem { Value = cat.ID.ToString(), Text = cat.categoryName }; 

       if (id > 0 && cat.ID == id) 
       { 
        sli.Selected = true; 
       } 
       list.Add(sli); 
      } 
      return list; 
     } 

    } 

    public ProductModel() 
    { 
     active = true; 
    } 

} 

Вот метод в контроллере, который заполняет списки:

public ActionResult ControlPanel() 
    { 
     ViewBag.Message = TempData["Message"] == null ? "" : TempData["Message"].ToString(); 

     //using (var db = new ProductContext()) 
     //{ 
     // var categories = from c in db.Categories 
     //     select c; 
     // categories = categories.OrderByDescending(c => c.isActive); 
     // var model = new AdminModel 
     // { 
     //  Categories = categories.ToList(), 
     //  Products = db.Products.ToList(), 
     //  RegisterUsers = db.RegisterViewModels.ToList() 
     // }; 

     // return View(model); 
     //} 

     var model = new AdminModel(); 
     using (var db = new ProductContext()) 
     { 
      var categories = from c in db.Categories 
          select c; 
      categories = categories.OrderByDescending(c => c.isActive); 
      model.Categories = categories.ToList(); 
      model.Products = db.Products.ToList(); 
      model.Brochures = db.Brochures.ToList(); 

     }; 

я, вероятно, что-то неправильно в ListBoxFor линии и может быть, что-то не так в моей модели, но я не уверен.

+0

как ваш контроллер заполняется? – code

ответ

1

Недвижимость model.ProductCategories is ICollection<CategoryModel>. Вы не можете привязать <select multiple> к набору сложных объектов, а только к набору типов значений. Предполагая, что Category.ID является TypeOf int тогда ваша модель должна свойство (скажем)

public int[] SelectedCategories { get; set; } // or List<int> 

, а затем в представлении

@Html.ListBoxFor(m => m.SelectedCategories, Model.CategorySelectList, new { @class = "chzn-select", data_placeholder = "Choose categorie(s)..."}) 

В вы POST метод, SelectedCategories будет содержать выбранные категории идентификаторов.

Отметим также Model.CategorySelectList уже IEnumerable<SelectListItem> создавая таким образом новую IEnumerable<SelectListItem> от него (как вы делаете с .Select(c => new SelectListItem { Text = c.Text, Value = c.Value }) просто бессмысленно дополнительные накладные расходы.

Кроме того, следующий код в методе getCategories() также бессмысленно.

if (id > 0 && cat.ID == id) { sli.Selected = true; } 

Поскольку вы строго привязываетесь к свойству модели, его значение свойства, привязка которого определяет, какие параметры будут выбраны, и свойство SelectedSelectListItem - это sim игнорируется. Если вы хотите предварительно выбрать параметры, установите в контроллере значение SelectedCategories. Например, если model.SelectedCategories = new int[] { 1, 3 } и ваши параметры имеют значения от 1 до 10, тогда будут выбраны 1-й и 3-й варианты.

+0

Это очень полезно, спасибо! Могу ли я задать еще один вопрос: как я перечисляю категории в другом разделе моего представления? Я продолжаю получать ошибку: Шаблоны могут использоваться только с доступом к полю, доступом к ресурсам, индексом одномерного массива или однопараметрическими пользовательскими выражениями индексатора. – dmikester1

+0

Это то, что я пробовал: ' Категория: @ Html.DisplayFor (modelItem => item.ProductCategories.ToString())' – dmikester1

+0

Кроме того, мне нужно получить 'SelectedCategories', добавленный в мои продукты Таблица? Когда я пытаюсь запустить «ToList()» на своих Продуктах, он жалуется, что столбцы «SelectedCategories» не существуют. – dmikester1