asp.net mvc - Model binding doesn't work when multiple instances of the same partial view are called dynamically with ajax.actionlink in MVC 5 -


i'm building restaurant reservations system. when user creates reservation can decided furniture used reservation. created partial view, every time user click on "add furniture" partial view loaded ajax user can specify furniture , how many. can add many types of furniture want, meaning can call partial view many times want. problem comes in model binder, model binder have bind partial view instances list object of type "bistroreservations_reservationsfurniture". please how make model binder work.

mainview (please have @ bottom ajax.actionlink call "add furniture"

@using (html.beginform())  

{ @html.antiforgerytoken()

<div class="form-horizontal">     <h4>bistroreservations_reservation</h4>     <hr />     @html.validationsummary(true, "", new { @class = "text-danger" })     <div class="form-group">         @html.labelfor(model => model.dateofarrival, htmlattributes: new { @class = "control-label col-md-2" })         <div class="col-md-10">             @html.editorfor(model => model.dateofarrival, new { htmlattributes = new { @class = "form-control datecontrol" } })             @html.validationmessagefor(model => model.dateofarrival, "", new { @class = "text-danger" })         </div>     </div>      <div class="form-group">         @html.labelfor(model => model.bistroreservations_shiftid, htmlattributes: new { @class = "control-label col-md-2" })         <div class="col-md-10">             @html.dropdownlist("bistroreservations_shiftid", null, htmlattributes: new { @class = "form-control" })             @html.validationmessagefor(model => model.bistroreservations_shiftid, "", new { @class = "text-danger" })         </div>     </div>  <div class="form-group">     @html.labelfor(model => model.bistroreservations_guestid, htmlattributes: new { @class = "control-label col-md-2" })     <div class="col-md-6">         @html.dropdownlist("bistroreservations_guestid", null, htmlattributes: new { @class = "form-control" })              @html.validationmessagefor(model => model.bistroreservations_guestid, "", new { @class = "text-danger " })          @ajax.actionlink("create new guest", "newguest", new ajaxoptions        {            httpmethod = "get",            updatetargetid = "newguest",            insertionmode = insertionmode.replacewith,                                      })                 </div> </div>             <div id="newguest" class="form-group">     </div>     <br />      <div class="form-group">         @html.labelfor(model => model.arrivaltime, htmlattributes: new { @class = "control-label col-md-2" })         <div class="col-md-10">             @html.dropdownlist("arrivaltime", null, htmlattributes: new { @class = "form-control" })             @html.validationmessagefor(model => model.arrivaltime, "", new { @class = "text-danger" })         </div>     </div>         <div class="form-group">         @html.labelfor(model => model.locationid, htmlattributes: new { @class = "control-label col-md-2" })         <div class="col-md-10">             @html.dropdownlist("locationid", null, htmlattributes: new { @class = "form-control" })             @html.validationmessagefor(model => model.locationid, "", new { @class = "text-danger" })         </div>     </div>         <div class="form-group">         @html.labelfor(model => model.bistroreservations_typeofseatingid, htmlattributes: new { @class = "control-label col-md-2" })         <div class="col-md-10">             @html.dropdownlist("bistroreservations_typeofseatingid", null, htmlattributes: new { @class = "form-control" })             @html.validationmessagefor(model => model.bistroreservations_typeofseatingid, "", new { @class = "text-danger" })         </div>     </div>      <div class="form-group">         @html.labelfor(model => model.tablenoid, htmlattributes: new { @class = "control-label col-md-2" })         <div class="col-md-10">             @html.dropdownlist("tablenoid", null, htmlattributes: new { @class = "form-control" })             @html.validationmessagefor(model => model.tablenoid, "", new { @class = "text-danger" })         </div>     </div>      <div class="form-group">         @html.labelfor(model => model.bistroreservations_statusid, "bistroreservations_statusid", htmlattributes: new { @class = "control-label col-md-2" })         <div class="col-md-10">             @html.dropdownlist("bistroreservations_statusid",null, htmlattributes: new { @class = "form-control" })             @html.validationmessagefor(model => model.bistroreservations_statusid, "", new { @class = "text-danger" })         </div>     </div>      <div class="form-group">         @html.labelfor(model => model.comment, htmlattributes: new { @class = "control-label col-md-2" })         <div class="col-md-10">             @html.editorfor( model => model.comment, new { htmlattributes = new { @class = "form-control" } })             @html.validationmessagefor(model => model.comment, "", new { @class = "text-danger" })              @ajax.actionlink("add furniture", "furniture", new ajaxoptions        {            httpmethod = "get",            updatetargetid = "furniture",            insertionmode = insertionmode.insertafter        })          </div>     </div>        <div id="furniture" class="form-group">     </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> 

}

actionresult returning furniture partial view

public partialviewresult furniture()     {          viewbag.bistroreservations_furnitureid = new selectlist(db.bistroreservations_furnitures, "bistroreservations_furnitureid", "description");          return partialview("_furniture");     } 

furniture partial view

@model cdvportal.models.bistroreservations.bistroreservations_reservationfurniture  <div class="form-horizontal">     <hr />     @html.validationsummary(true, "", new { @class = "text-danger" })     <div class="form-group">         @html.labelfor(model => model.bistroreservations_furnitureid, htmlattributes: new { @class = "control-label col-md-2" })         <div class="col-md-10">             @html.dropdownlist("bistroreservations_furnitureid", null, htmlattributes: new { @class = "form-control" })             @html.validationmessagefor(model => model.bistroreservations_furnitureid, "", new { @class = "text-danger" })         </div>     </div>      <div class="form-group ">         @html.labelfor(model => model.quantity, htmlattributes: new { @class = "control-label col-md-2" })         <div class="col-md-10">             @html.editorfor(model => model.quantity, new { htmlattributes = new { @class = "form-control" } })             @html.validationmessagefor(model => model.quantity, "", new { @class = "text-danger" })         </div>     </div>       </div> 

furniture model

 public class bistroreservations_reservationfurniture {     public int bistroreservations_reservationfurnitureid { get; set; }      public int bistroreservations_reservationid { get; set; }            public virtual bistroreservations_reservation bistroreservations_reservation { get; set; }      [display(name="furniture type")]     public int bistroreservations_furnitureid { get; set; }     public virtual bistroreservations_furniture bistroreservations_furniture { get; set; }      public int quantity { get; set; } } 

you @ajax.actionlink() method returning views duplicate id attributes (invalid html) , duplicate name attributes not prefixed correct property name , not include indexers binding collection. example if collection property named furnitureitems html needed quantity property of typeof bistroreservations_reservationfurniture need be

<input type="text" name="furnitureitems[0].quantity" ...> <input type="text" name="furnitureitems[1].quantity" ...> 

you can use begincollectionitem helper generate controls, might (assuming property named furnitureitems)

@model cdvportal.models.bistroreservations.bistroreservations_reservationfurniture @using (html.begincollectionitem("furnitureitems")) {   ....   @html.labelfor(m => m.quantity, ..)   @html.editorfor(m => m.quantity, ..)   @html.validationmessagefor(m => m.quantity, ..) } 

this generate correct prefix , add include indexer based on guid allows delete items collection. this article explains usage in more detail

a pure client side alternative shown in this answer. gives better performance, harder maintain since changing in bistroreservations_reservationfurniture model means updating client side template.


Comments

Popular posts from this blog

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -

ubuntu - Selenium Node Not Connecting to Hub, Not Opening Port -