c# - MVC 5: ViewModel / Passing lists for the create -


so studying , analyzing use of viewmodels.

in application (a called "restaurant") want ability "users" create menu.

when want create menu: can choose name + amount of persons can join menu. also, can add amount of dishes in restaurant. in style of checkboxes , 'create'-button @ end.

this means had use viewmodel. trying give possibility add list of dishes menu creation. i'm stuck @ loop, used loop through dishes. or better, i'm stuck @ whole concept:

  • what best way display created dishes createmenu view? still possible loop through viewbag if add them in viewbag?

  • lets tried wanted do. how create new menu based (or extracted?) viewmodel?

in code, please note menu - model cannot changed because use list of dishes (in view, display menu's , dishes).

also ignore possibility of wrong names or spelling mistakes in data, since translated flemish

models

public class menu {     [key]     public int id { get; set; }     [required]     public string name { get; set; }     [range(0,10)]     public int amountpersons { get; set; }     [range(0,double.maxvalue)]     public double price { get; set; }     public virtual list<dish> dishes { get; set; } }  public class dish {     [required]     public int id { get; set; }     [required]     public string name { get; set; }     public enum types { voorgerecht, hoofdgerecht, drank, dessert}     public types type { get; set; }     public double price { get; set; }     public virtual list<menu> menus { get; set; }     public virtual list<table> tables { get; set; }     //checked used 'checkbox' in createmenu-view     [notmapped]     public bool checked { get; set; } }  public class menuviewmodel {     public menu menu { get; set; }     public list<dish> addeddishes { get; set; } } 

controller

public actionresult createmenu( ) {     menuviewmodel gm = new menuviewmodel();     // assign created dishes list user can choose.     // addeddishes wrong? viewbag preferred?     gm.addeddishes = db.dishes.tolist();     return view(gm); }  // add menu menu's in database. [httppost] public actionresult menuaanmaken(menumodel gm) {     // code save menu added dishes database     // conflict!? cannot convert menuviewmodel menu-model how need extract menu , addeddishes list      // menu , save 1 database?     db.menus.add(gm);     return view(gm); } 

view

@using vbexamen.models @model menuviewmodel ....  @html.labelfor(m => m.menu.name) @html.editorfor(m => m.menu.name) @html.labelfor(m => m.menu.amountpersons) @html.editorfor(m => m.menu.amountpersons)  @for(int = 0; < model.addeddishes.count; i++) {     <tr>         <td>             @html.displayfor( .name)             @html.hiddenfor(item => .id)             @html.checkboxfor(item => .checked)         </td>     </tr> } 

e d t e d _ u p d t e (see below) okay think i'm close now,

i edited classes following:

public class menuviewmodel<t> {     public menu menu { get; set; }     public list<t> dishlist { get; set; }     public menuviewmodel()     {         this.lijst = new list<t>();     } } 

controller

public actionresult createmenu(menuviewmodel<dish> model ) {     model.dishlist = db.gerechten.tolist();     return view(model); }  [httppost] public actionresult createmenu(menuviewmodel<dish> model,list<gerecht> selectedlist) {     menu t = new menu();     t.naam = gm.menu.naam;     t.amountpersons = gm.menu.amountpersons;     t.dishes = selectedlist;     db.menus.add(t);     return view("menus", model); } 

view function creating list

@for (int = 0; < model.dishlist.count(); i++) {     <tr>         <td>             @html.label(model.dishlist[i].naam)             <input type="hidden" name=@string.format("dishlist[{0}].id", i) value=@model.dishlist.elementat(i).id />             <input type="hidden" name=@string.format("dishlist[{0}].name", i) value=@model.dishlist.elementat(i).name />             <input type="checkbox" name=@string.format("dishlist[{0}].value", i) />             <input type="hidden" name=@string.format("dishlist[{0}].value", i) value="false" />         </td>         <br />     </tr> } 

i did after watching 10 tutorials viewmodels, next approach better first one?

i think because following on screen:

enter image description here

i thinking next approach be. thinking comparing 2 lists (1 of viewmodel, 1 passed) , see checkbox statuses?

update

after stephen muecke's answer re-edited code found problem can't seem understand.

the answer says should in position of 1-to-many table in form class:

// have not indicated 1-many table dishes saved adjust required         menudish dish = new menudish()         {             menuid = menu.id,             dishid = dish         };         db.menudishes.add(dish); 

however, we've learned @ school was, if create lists in data-models of entities, linked tables automatically generated in database. , db has done (without creation of menudish class):

menugerechts stands menudish. automatically created table done entity framework. enter image description here brings me following questions. have re-edited controller following:

 [httppost]         public actionresult menuaanmaken(menuvm model)         {             if (!modelstate.isvalid)             {                 return view(model);             }              ienumerable<int> selecteddishes = model.dishes.where(x => x.isselected).select(x => x.id);             menu menu = new menu()             {                 naam = model.name,                 aantalpersonen = model.amountpersons             };               foreach (int id in selecteddishes)                 {                     dish g = db.dishes.find(id);                     menu.dishes.add(g);                  };              db.menus.add(menu);             db.savechanges();               return redirecttoaction("menus", "menu");         } 

i object reference not set instance of object error , i'm understanding why ofcourse.

i have done changes since data-model menu, has list of dishes. assuming answer of s. muecke, isn't correct way solve viewmodel since proposes use of new class (that created support one-to-many relationship)?

this brings me conclusion of following questions:

  • why impossible or not-recommended directly add selected dishes menu instance?

  • is needed create in between table 'menudish' in data-model?

  • will following code still work (showing menu's , dishes) after creating new menu's?:

controller:

   public actionresult menus()             {                 list<menu> menus = db.menus.tolist();                 return view(menus);             } 

view:

@model ienumerable<vbexamen.models.menu>  @{     viewbag.title = "menus"; }  <h2>menus</h2>  <p>     @html.actionlink("create new menu", "createmenu") </p>  @foreach (var item in model) {     <table>           <ul>             <p>@html.displayfor(modelitem => item.name)</p>              @foreach (var g in item.dishes)             {                 <li>                     @html.displayfor(modelitem => g.name)                 </li>             }         </ul>     </table> } 

which outputs following:

enter image description here

what motivations this?

update 2

so have included following in project: ** have used table()- annotation make use 1 that's created**

  • **model: **

    [table("menugerechts")] public class menugerechts { [key] [foreignkey("menu")] public virtual int? menuid { get; set; } public virtual menu menu { get; set; }

        [foreignkey("dish")]     public virtual int? dishid { get; set; }     public virtual dish dish { get; set; } } 

i have created new menus successfully! when go overview menu page (from pic above), shows name of menu, , not list of meals includes.

the database didn't allow menudish link table used newly created class (it created new one, , renamed old 1 'old' menus '1' behind it:

enter image description here

hence why asking previous questions. mean whole approach exercise wrong?

new question: menucreate viewmodel works if select 1 dish? why so? following error the role 'menugerechts_menu_source' of relationship 'vbexamen.models.menugerechts_menu' has multiplicity 1 or 0..1.

firstly view model should not contain properties data models. should contains properties display/edit in view, , recommend read what viewmodel in mvc?.

based in image of form have shown, view models needs (display , validation attributes omitted simplicity)

public class menuvm {     public int? id { get; set; } // included can used editing creating     public string name { get; set; }     public int amountpersons { get; set; }     public list<dishvm> dishes { get; set; } } public class dishvm {     public int id { get; set; }     public string name { get; set; }     public bool isselected { get; set; } } 

and controller method

public actionresult createmenu( ) {     // dishes database     var dishes = db.dishes; // modify suit     // initialize view model     var model = new menuvm()     {         dishes = dishes.select(x => new dishvm()         {             id = x.id,             name = x.name         }).tolist()     };     return view(model); } 

then in view (labelfor() , validationfor() methods omitted simplicity)

@model menuvm @using (html.beginform()) {     @html.textboxfor(m => m.name)     @html.textboxfor(m => m.amountpersons )     for(int = 0; < model.dishes.count; i++)     {         <div>             @html.hiddenfor(m => m.dishes[i].id)             @html.hiddenfor(m => m.dishes[i].name)             @html.checkboxfor(m => m.dishes[i].isselected)             @html.labelfor(m => m.dishes[i].isselected, model.dishes[i].name)         </div>     }     <input type="submit" value="create" /> } 

and post method be

public actionresult createmenu(menuvm model) {     if (!modelstate.isvalid)     {         return view(model);     }     // initialize , save menu     menu menu = new menu()     {         name = model.name,         amountpersons = model.amountpersons     };     db.menus.add(menu);     db.savechanges(); // have id of new menu     // save dishes associated menu     ienumerable<int> selecteddishes = model.dishes.where(x => x.isselected).select(x => x.id);     foreach(int id in selecteddishes)     {         // have not indicated 1-many table dishes saved adjust required         menudish dish = new menudish()         {             menuid = menu.id,             dishid = dish         };         db.menudishes.add(dish);     }     db.savechanges(); // save selected dishes     return redirecttoaction(...); // redirect somewhere } 

side note: remove [notmapped] public bool checked { get; set; } property data model.


Popular posts from this blog

php - How should I create my API for mobile applications (Needs Authentication) -

5 Reasons to Blog Anonymously (and 5 Reasons Not To)

Google AdWords and AdSense - A Dynamic Small Business Marketing Duo