c# - CheckBoxList for many-to-many relationship in ASP.NET MVC -


i trying implement check box list in mvc many-to-many relationship (article - category). have tried this, not work. know different , approach it.

in domain model:

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

in view model:

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

in controller:

 public actionresult edit(int id)     {         //return article categories         article articletoedit = _repo.getarticlecategories(id);            mapper.createmap<article, articlescategoriesviewmodel>();         mapper.createmap<category, categoriesviewmodel>();              articlescategoriesviewmodel article = mapper.map<article, articlescategoriesviewmodel>(articletoedit);         //return 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);     } 

in view model:

<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> 

it works show categories of article, when submit post new categories selected, model not valid.

this post method:

  [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 found. operation not valid.");                 return view(articletoedit);             }         }          modelstate.addmodelerror("", "one or more erros found. model-binding operation not valid.");         return view(articletoedit);      } 

i have got null references error when mvc model-data-binding try match data, apparently happens when matching collections "allcategories", "categories" of model view. appreciate help.

you should use view model category has properties describe want display/edit in view

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

view

for(int = 0; < 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) } 

in method, initialize articlescategoriesviewmodel based on id, , add categoryvm each available category , set isselected property based on categories assigned article. in post method, can selected categories var selectedcategories = articletoedit.categories.where(c => c.isselected).

you should remove [bind(include="..")] attribute. view model represents display/edit in view unnecessary since should not excluding properties.