c# - Strongly-Typed Model Not Posting from Partial View -
i have mvc3 page comprised of following components:
profilecontroller - contains of actions , loads of views below
/profile/index - action method creates instance of userviewmodel, contains several properties , nested collections, including 1 called "prefprograms" of type "preferenceprograms," defined as:
public class preferenceprograms : list<preferenceprogram> the "index" action method populates prefprograms collection , rest of userviewmodel , passes model typed "index.cshtml" view.
index.cshtml - strongly-typed view of type "userviewmodel." comprised of multiple partial views. 1 partial view within page, named "preferences.cshtml," provides formatted display of prefprograms collection. relevant portion of index.cshtml below.
@model profilepreferencecenterproto.models.userviewmodel @{ html.renderpartial("preferences", model); } preferences.cshtml - strongly-typed partial view loaded index.cshtml using html.renderpartial (above). within preferences.cshtml, have begin.ajaxform() method posting "preferencesubmit" action , input submit button @ bottom of partial view. within partial view, call @html.editorfor() helper load editor template each "preferenceprogrammodel" item in "prefprograms" collection.
here's problem - items load correctly (including partial view , editorfor components), when post form on preferences.cshtml "preferencessubmit" action, model's values not passed (the model instantiated, values initialized - property , collection values not passed controller).
the preferences.cshtml partial view shown below.
@model profilepreferencecenterproto.models.userviewmodel <div id="accordian"> @using(ajax.beginform("preferencessubmit", "profile", new ajaxoptions{ updatetargetid = "accordian" })){ <div id="accordion"> <ul class="tabs"> </ul> <div class="panes"> <div> @{ list<string> affiliatenames = new list<string>(); foreach(profilepreferencecenterproto.models.preferenceprogrammodel list in model.prefprograms) { affiliatenames.add(list.subcategoryname); } ienumerable<string> listnames = affiliatenames.distinct(); int counter = 0; } @foreach (string accordiontabname in listnames) { <h2>@accordiontabname</h2> <div class="pane" @if (counter == 0){ <text>style="display:block;"</text> } > <table> <tr class="row"> <th class="name">subscription</th> <th class="icon">email</th> <th class="icon">sms</th> <th class="icon">facebook</th> <th class="icon">mail</th> <th class="icon">phone</th> </tr> @{ counter++; var tabprograms = (from l in model.prefprograms l.subcategoryname == @accordiontabname select l); } @html.editorfor(m => tabprograms) </table> </div> } </div> </div> </div> <div align="center"><input type="submit" value="save preferences" /></div> }
/shared/editortemplates/preferenceprogrammodel.cshtml - editor template "preferenceprogrammodel" items, defined follows:
@model profilepreferencecenterproto.models.preferenceprogrammodel <tr class="row"> <td class="name">@model.listname</td> <td class="icon"> @if (model.emailenabled) { <a id="@model.emailfilterid" href="#" onclick="imageclick(@html.idfor(m => m.emailstatus));"><img height="25" width="28" src="@model.email_icon_notselected" /></a> } </td> <td class="icon"> @if (model.smsenabled) { <a id="@model.smsfilterid" href="#"><img height="25" width="28" src="@model.sms_icon_notselected" /></a> } </td> <td class="icon"> @if (model.fbenabled) { <a id="@model.fbfilterid" href="#"><img height="25" width="28" src="@model.fb_icon_notselected" /></a> } </td> <td class="icon"> @if (model.mailenabled) { <a id="@model.mailfilterid" href="#"><img height="25" width="28" src="@model.mail_icon_notselected" /></a> } </td> <td class="icon"> @if (model.phoneenabled) { <a id="@model.phonefilterid" href="#"><img height="25" width="28" src="@model.phone_icon_notselected" /></a> } </td> </tr> @html.hiddenfor(m => m.emailstatus) @html.hiddenfor(m => m.smsstatus) @html.hiddenfor(m => m.fbstatus) @html.hiddenfor(m => m.mailstatus) @html.hiddenfor(m => m.phonestatus) <script type="text/javascript"> $(document).ready(function () { function imageclick(resource) { alert(resource.attr("value")); if (resource.attr("value") != 1) { resource.val("1"); } else { resource.val("2"); } alert(resource.attr("value")); } if ("@model.emailenabled" == "true") { $("#@model.emailfilterid").click(function () { imageclick($("#@html.idfor(m => m.emailstatus)")); return false; }); } if ("@model.smsenabled" == "true") { $("#@model.smsfilterid").click(function () { imageclick($("#@html.idfor(m => m.smsstatus)")); return false; }); } if ("@model.fbenabled" == "true") { $("#@model.fbfilterid").click(function () { imageclick($("#@html.idfor(m => m.fbstatus)")); return false; }); } if ("@model.mailenabled" == "true") { $("#@model.mailfilterid").click(function () { imageclick($("#@html.idfor(m => m.mailstatus)")); return false; }); } if ("@model.phoneenabled" == "true") { $("#@model.phonefilterid").click(function () { imageclick($("#@html.idfor(m => m.phonestatus)")); return false; }); } }); </script> the preferencessubmit controller action defined signature:
public actionresult preferencessubmit(models.userviewmodel model) the rendered form tag the page below:
<form action="/profile/preferencessubmit" data-ajax="true" data-ajax-mode="replace" data-ajax-update="#accordian" id="form0" method="post"> some of rendered hidden fields shown below:
<input data-val="true" data-val-number="the field emailstatus must number." data-val-required="the emailstatus field required." id="tabprograms_0__emailstatus" name="tabprograms[0].emailstatus" type="hidden" value="0" /> <input data-val="true" data-val-number="the field smsstatus must number." data-val-required="the smsstatus field required." id="tabprograms_0__smsstatus" name="tabprograms[0].smsstatus" type="hidden" value="0" /> <input data-val="true" data-val-number="the field fbstatus must number." data-val-required="the fbstatus field required." id="tabprograms_0__fbstatus" name="tabprograms[0].fbstatus" type="hidden" value="0" /> <input data-val="true" data-val-number="the field mailstatus must number." data-val-required="the mailstatus field required." id="tabprograms_0__mailstatus" name="tabprograms[0].mailstatus" type="hidden" value="0" /> <input data-val="true" data-val-number="the field phonestatus must number." data-val-required="the phonestatus field required." id="tabprograms_0__phonestatus" name="tabprograms[0].phonestatus" type="hidden" value="0" /> i've verified modelstate.isvalid true when preferencessubmit called, model not contain actual values page. how pass strongly-typed model values partial view action method on submit?
the values submited form binded properties of model based on names of properties of model , names of fields in html. in code:
var tabprograms = (from l in model.prefprograms l.subcategoryname == @accordiontabname select l); } @html.editorfor(m => tabprograms) htmlhelper not know names of properties in userviewmodel. takes "tabprograms" local variable name in order generate names of fields in html like:
<input name="tabprograms[0].emailstatus" data-val="true" data-val-number="the field emailstatus must number." data-val-required="the emailstatus field required." id="tabprograms_0__emailstatus" type="hidden" value="0" /> so mvc try bind value field above property named "tabprograms" in userviewmodel (and should collection of preferenceprogrammodel objects). have "tabprograms" property in userviewmodel class? if not, should create , data these fields bound it. another, better, solution use "prefprograms" local variable name instead of "tabprograms"
Comments
Post a Comment