2015-04-28 27 views
0

我想在MVC中實現一個多對多關係(Article-Category)的複選框列表。我已經嘗試過,但我沒有工作。有沒有人知道一個不同的,正確的方法來獲得它。CheckBoxList在ASP.NET MVC中的多對多關係

在域模型:

public class Article 
{ 

    public int Id { get; set; } 


    [Required] 
    [StringLength(255)] 
    public string Title { get; set; } 

    [Required] 
    public string Body { get; set; } 

    [Required] 
    public DateTime DateCreated { get; set; } 

    [Required] 
    [StringLength(255)] 
    public string Author { get; set; } 


    public ICollection<ArticleComment> Comments { get; set; } 
    public ICollection<Category> Categories { get; set; } 

} 

在視圖型號:

public class ArticlesCategoriesViewModel 
{ 

    public int Id { get; set; } 
    [Required] 
    public string Title { get; set; } 

    [Required] 
    [UIHint("tinymce_jquery_full"), AllowHtml] 
    public string Body { get; set; } 

    [Required] 
    [DataType(DataType.Date)] 
    [Display(Name = "Publication Date")] 
    public DateTime DateCreated { get; set; } 

    [Required] 
    public string Author { get; set; } 

    public IEnumerable<CategoriesViewModel> Categories { get; set; } 
    public IEnumerable<CategoriesViewModel> AllCategories { get; set; } 
    public string[] PostedCategories { get; set; } 
} 

在控制器:

public ActionResult Edit(int id) 
    { 
     //Return article with its categories 
     Article articleToEdit = _repo.GetArticleCategories(id); 
     Mapper.CreateMap<Article, ArticlesCategoriesViewModel>(); 
     Mapper.CreateMap<Category, CategoriesViewModel>();  
     ArticlesCategoriesViewModel article = Mapper.Map<Article, ArticlesCategoriesViewModel>(articleToEdit); 
     //Return all categories 
     IEnumerable<Category> allCategories = _repo.GetAllCategories(); 
     IEnumerable<CategoriesViewModel> AllCategories = Mapper.Map <IEnumerable<Category>, IEnumerable<CategoriesViewModel>>(allCategories); 

     article.AllCategories = AllCategories; 

     if (articleToEdit == null) 
     { 
      return HttpNotFound(); 
     } 

     return View(article); 
    } 

在視圖模型:

<ul> 
    @foreach (var g in Model.AllCategories) 
    { 
     <li> 
      <input type="checkbox" name="PostedCategories" value="@g.Id" id="@g.Id" 
       @{if (Model.Categories.FirstOrDefault(h => h.Id == g.Id) != null) { <text> checked='checked' </text> } } /> 
      <label for="@g.Id">@g.Name</label> 
     </li> 
    } 
</ul> 

它可以顯示文章的所有類別,但是當我提交到POST時,我的新類別被選中,我的模型無效。

這是我Post方法:

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult Edit([Bind(Include = "Id,Title,Body,DateCreated,Author,PostedCategories")]ArticlesCategoriesViewModel articleToEdit) 
    { 

     if (ModelState.IsValid) 
     { 
      Mapper.CreateMap<ArticlesCategoriesViewModel, Article>(); 
      Article article = Mapper.Map<ArticlesCategoriesViewModel, Article>(articleToEdit); 

      if (_repo.EditArticle(article) && _repo.Save()) 
      { 
       return RedirectToAction("Index"); 
      } 

      else 
      { 
       ModelState.AddModelError("", "One or more erros were found. Operation was not valid."); 
       return View(articleToEdit); 
      } 
     } 

     ModelState.AddModelError("", "One or more erros were found. Model-binding operation was not valid."); 
     return View(articleToEdit); 

    } 

我有當MVC模型數據綁定嘗試匹配數據空引用錯誤,當它匹配的集合「AllCategories」,「分類顯然發生「我的模型觀點。 我真的很感激任何幫助。

+0

您是否試圖選擇與某篇文章相關的一個或多個類別? –

+0

我想向用戶展示所有可用的類別,並顯示與文章相關的所有類別。因此用戶可以選擇新的或未選中的舊的。 – user3007593

+0

您確實需要爲類別使用適當的視圖模型。你目前的'CategoriesViewModel'是什麼? –

回答

1

您應該使用視圖模型Category其中有描述您要在視圖中顯示/編輯

public class CategoryVM 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public bool IsSelected { get; set; } 
} 

public class ArticlesCategoriesViewModel 
{ 
    public int Id { get; set; } 
    .... 
    public string Author { get; set; } 
    List<CategoryVM> Categories { get; set; } 
} 

查看

for(int i = 0; i < Model.Categories.Count; i++) 
{ 
    @Html.CheckBoxFor(m => m.Categories[i].IsSelected) 
    @Html.LabelFor(m => m.Categories[i].IsSelected, Model.Categories[i].Name) 
    @Html.HiddenFor(m => m.Categories[i].ID) 
    @Html.HiddenFor(m => m.Categories[i].Name) 
} 

在GET方法,初始化ArticlesCategoriesViewModel什麼性質基於ID,併爲每個可用類別添加CategoryVM,並根據已分配給文章的類別設置IsSelected屬性。在POST方法中,您可以使用var selectedCategories = articleToEdit.Categories.Where(c => c.IsSelected)獲取選定的類別。

您還應該刪除[Bind(Include="..")]屬性。視圖模型僅代表您在視圖中顯示/編輯的內容,因此您不應該排除任何屬性。

+0

謝謝斯蒂芬。我已經實施你的方法。它工作正常。 – user3007593