Note that there are some explanatory texts on larger screens.

plurals
  1. POStrongly-Typed Model Not Posting from Partial View
    primarykey
    data
    text
    <p>I have an MVC3 page comprised of the following components:</p> <p><em><strong>ProfileController</em></strong> - Contains all of the actions and loads all of the views below</p> <p><em><strong>/Profile/Index</em></strong> - This action method creates an instance of UserViewModel, which contains several properties and nested collections, including one called "PrefPrograms" which is of type "PreferencePrograms," which is defined as:</p> <pre><code>public class PreferencePrograms : List&lt;PreferenceProgram&gt; </code></pre> <p>The "Index" action method populates the PrefPrograms collection and the rest of the UserViewModel and passes that model into the strongly typed "Index.cshtml" view.</p> <p><em><strong>Index.cshtml</em></strong> - This is a strongly-typed view of type "UserViewModel." It is comprised of multiple partial views. One partial view within this page, named "Preferences.cshtml," provides a formatted display of the PrefPrograms collection. The relevant portion of Index.cshtml is below.</p> <pre><code>@model ProfilePreferenceCenterProto.Models.UserViewModel @{ Html.RenderPartial("Preferences", Model); } </code></pre> <p><em><strong>Preferences.cshtml</em></strong> - This strongly-typed partial view is loaded by Index.cshtml using Html.RenderPartial (above). Within Preferences.cshtml, I have a Begin.AjaxForm() method for posting to a "PreferenceSubmit" action and the input submit button is at the bottom of this partial view. Within the partial view, I call an @Html.EditorFor() helper to load an Editor Template for each "PreferenceProgramModel" item in the "PrefPrograms" collection.</p> <p><strong><em>Here's my problem - all items load correctly (including the partial view and editorfor components), but when I post the form on Preferences.cshtml to the "PreferencesSubmit" action, the model's values are not passed (the model is instantiated, but the values are only initialized - the property and collection values are not actually passed back to the controller).</em></strong></p> <p>The Preferences.cshtml Partial View is shown below.</p> <pre><code>@model ProfilePreferenceCenterProto.Models.UserViewModel &lt;div id="accordian"&gt; @using(Ajax.BeginForm("PreferencesSubmit", "Profile", new AjaxOptions{ UpdateTargetId = "accordian" })){ &lt;div id="accordion"&gt; &lt;ul class="tabs"&gt; &lt;/ul&gt; &lt;div class="panes"&gt; &lt;div&gt; @{ List&lt;string&gt; AffiliateNames = new List&lt;string&gt;(); foreach(ProfilePreferenceCenterProto.Models.PreferenceProgramModel list in Model.PrefPrograms) { AffiliateNames.Add(list.SubcategoryName); } IEnumerable&lt;string&gt; listNames = AffiliateNames.Distinct(); int counter = 0; } @foreach (string AccordionTabName in listNames) { &lt;h2&gt;@AccordionTabName&lt;/h2&gt; &lt;div class="pane" @if (counter == 0){ &lt;text&gt;style="display:block;"&lt;/text&gt; } &gt; &lt;table&gt; &lt;tr class="row"&gt; &lt;th class="name"&gt;Subscription&lt;/th&gt; &lt;th class="icon"&gt;Email&lt;/th&gt; &lt;th class="icon"&gt;SMS&lt;/th&gt; &lt;th class="icon"&gt;Facebook&lt;/th&gt; &lt;th class="icon"&gt;Mail&lt;/th&gt; &lt;th class="icon"&gt;Phone&lt;/th&gt; &lt;/tr&gt; @{ counter++; var TabPrograms = (from l in Model.PrefPrograms where l.SubcategoryName == @AccordionTabName select l); } @Html.EditorFor(m =&gt; TabPrograms) &lt;/table&gt; &lt;/div&gt; } &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;div align="center"&gt;&lt;input type="submit" value="Save Preferences" /&gt;&lt;/div&gt; </code></pre> <p>} </p> <p><em><strong>/Shared/EditorTemplates/PreferenceProgramModel.cshtml</em></strong> - The Editor Template for "PreferenceProgramModel" items, defined as follows:</p> <pre><code>@model ProfilePreferenceCenterProto.Models.PreferenceProgramModel &lt;tr class="row"&gt; &lt;td class="name"&gt;@Model.ListName&lt;/td&gt; &lt;td class="icon"&gt; @if (Model.EmailEnabled) { &lt;a id="@Model.EmailFilterID" href="#" onclick="ImageClick(@Html.IdFor(m =&gt; m.EmailStatus));"&gt;&lt;img height="25" width="28" src="@Model.Email_Icon_NotSelected" /&gt;&lt;/a&gt; } &lt;/td&gt; &lt;td class="icon"&gt; @if (Model.SMSEnabled) { &lt;a id="@Model.SMSFilterID" href="#"&gt;&lt;img height="25" width="28" src="@Model.SMS_Icon_NotSelected" /&gt;&lt;/a&gt; } &lt;/td&gt; &lt;td class="icon"&gt; @if (Model.FBEnabled) { &lt;a id="@Model.FBFilterID" href="#"&gt;&lt;img height="25" width="28" src="@Model.FB_Icon_NotSelected" /&gt;&lt;/a&gt; } &lt;/td&gt; &lt;td class="icon"&gt; @if (Model.MailEnabled) { &lt;a id="@Model.MailFilterID" href="#"&gt;&lt;img height="25" width="28" src="@Model.Mail_Icon_NotSelected" /&gt;&lt;/a&gt; } &lt;/td&gt; &lt;td class="icon"&gt; @if (Model.PhoneEnabled) { &lt;a id="@Model.PhoneFilterID" href="#"&gt;&lt;img height="25" width="28" src="@Model.Phone_Icon_NotSelected" /&gt;&lt;/a&gt; } &lt;/td&gt; &lt;/tr&gt; @Html.HiddenFor(m =&gt; m.EmailStatus) @Html.HiddenFor(m =&gt; m.SMSStatus) @Html.HiddenFor(m =&gt; m.FBStatus) @Html.HiddenFor(m =&gt; m.MailStatus) @Html.HiddenFor(m =&gt; m.PhoneStatus) &lt;script type="text/javascript"&gt; $(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 =&gt; m.EmailStatus)")); return false; }); } if ("@Model.SMSEnabled" == "True") { $("#@Model.SMSFilterID").click(function () { ImageClick($("#@Html.IdFor(m =&gt; m.SMSStatus)")); return false; }); } if ("@Model.FBEnabled" == "True") { $("#@Model.FBFilterID").click(function () { ImageClick($("#@Html.IdFor(m =&gt; m.FBStatus)")); return false; }); } if ("@Model.MailEnabled" == "True") { $("#@Model.MailFilterID").click(function () { ImageClick($("#@Html.IdFor(m =&gt; m.MailStatus)")); return false; }); } if ("@Model.PhoneEnabled" == "True") { $("#@Model.PhoneFilterID").click(function () { ImageClick($("#@Html.IdFor(m =&gt; m.PhoneStatus)")); return false; }); } }); &lt;/script&gt; </code></pre> <p>The PreferencesSubmit controller action is defined with this signature:</p> <pre><code>public ActionResult PreferencesSubmit(Models.UserViewModel model) </code></pre> <p>The rendered form tag from the the page is below:</p> <pre><code>&lt;form action="/Profile/PreferencesSubmit" data-ajax="true" data-ajax-mode="replace" data-ajax-update="#accordian" id="form0" method="post"&gt; </code></pre> <p>Some of the rendered hidden fields are shown below:</p> <pre><code>&lt;input data-val="true" data-val-number="The field EmailStatus must be a number." data-val-required="The EmailStatus field is required." id="TabPrograms_0__EmailStatus" name="TabPrograms[0].EmailStatus" type="hidden" value="0" /&gt; &lt;input data-val="true" data-val-number="The field SMSStatus must be a number." data-val-required="The SMSStatus field is required." id="TabPrograms_0__SMSStatus" name="TabPrograms[0].SMSStatus" type="hidden" value="0" /&gt; &lt;input data-val="true" data-val-number="The field FBStatus must be a number." data-val-required="The FBStatus field is required." id="TabPrograms_0__FBStatus" name="TabPrograms[0].FBStatus" type="hidden" value="0" /&gt; &lt;input data-val="true" data-val-number="The field MailStatus must be a number." data-val-required="The MailStatus field is required." id="TabPrograms_0__MailStatus" name="TabPrograms[0].MailStatus" type="hidden" value="0" /&gt; &lt;input data-val="true" data-val-number="The field PhoneStatus must be a number." data-val-required="The PhoneStatus field is required." id="TabPrograms_0__PhoneStatus" name="TabPrograms[0].PhoneStatus" type="hidden" value="0" /&gt; </code></pre> <p>I've verified that ModelState.IsValid is true when PreferencesSubmit is called, but the model itself does not contain the actual values from the page. <strong><em>How do I pass my strongly-typed model values from the partial view back to the Action method on submit?</em></strong></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload