У меня есть страница MVC3, состоящая из следующих компонентов:Сильно типизированных Модель Не Проводка из частичного вида
ProfileController - Содержит все действия и нагрузки всех взглядов ниже
/Профиль/Индекс - Этот метод действий создает экземпляр UserViewModel, который содержит несколько свойств и вложенных коллекций, включая один, называемый PrefPrograms, который имеет тип «PreferencePrograms», который определяется как:
public class PreferencePrograms : List<PreferenceProgram>
Метод действия «Index» заполнит коллекцию PrefPrograms и остальную часть UserViewModel и передает эту модель в сильно типизированный «Index.cshtml».
Index.cshtml - "UserViewModel" Это сильно типизированных вид типа Он состоит из нескольких частичных представлений. Один частичный вид на этой странице с именем «Preferences.cshtml» обеспечивает форматированное отображение коллекции PrefPrograms. Соответствующая часть Index.cshtml приведена ниже.
@model ProfilePreferenceCenterProto.Models.UserViewModel
@{ Html.RenderPartial("Preferences", Model); }
Preferences.cshtml - Это сильно типизированных частичный вид загружается Index.cshtml используя Html.RenderPartial (выше). В Preferences.cshtml у меня есть метод Begin.AjaxForm() для отправки в действие «PreferenceSubmit», а кнопка ввода ввода находится в нижней части этого частичного представления. В частичном представлении я вызываю помощника @ Html.EditorFor() для загрузки шаблона редактора для каждого элемента «PreferenceProgramModel» в коллекции «PrefPrograms».
Вот моя проблема - все элементы правильно загрузить (в том числе частичного вида и editorfor компонентов), но когда я отправляю форму на Preferences.cshtml к действию «PreferencesSubmit», значение в модели не передается (модель , но значения инициализируются только - значения свойства и коллекции фактически не передаются обратно контроллеру).
Parental View Preferences.cshtml показан ниже.
@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
where l.SubcategoryName == @AccordionTabName
select l);
}
@Html.EditorFor(m => TabPrograms)
</table>
</div>
}
</div>
</div>
</div>
<div align="center"><input type="submit" value="Save Preferences" /></div>
}
/Общие/EditorTemplates/PreferenceProgramModel.cshtml - Редактор шаблон для элементов «PreferenceProgramModel», определяется следующим образом:
@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>
Действие контроллера PreferencesSubmit определяются с этой подписью:
public ActionResult PreferencesSubmit(Models.UserViewModel model)
Визуализированная формой тег от страницы находится ниже:
<form action="/Profile/PreferencesSubmit" data-ajax="true" data-ajax-mode="replace" data-ajax-update="#accordian" id="form0" method="post">
Некоторые из оказанных скрытых полей приведены ниже:
<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" />
<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" />
<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" />
<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" />
<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" />
Я проверял, что ModelState.IsValid является истинным, когда вызывается PreferencesSubmit, но сама модель не содержит фактических значений со страницы. Как передать мои сильно типизированные значения модели из частичного представления обратно в метод действия для отправки?
Этот подход определенно помог - я изменил «var TabPrograms» на теперь «var PrefPrograms», и теперь коллекция распознается в методе приема. При этом полная модель не заполнена, присутствует только часть модели, содержащаяся в форме. Есть ли способ получить полную модель для отправки? – Mike
@Mike: на сервер отправляются только поля, содержащиеся в HTML-форме. Вы можете добавить скрытые поля в свою форму с помощью Html.HiddenFor (m => m.FieldName), помните, что для коллекций вы должны перебирать все элементы и использовать для каждого свойства Html.HiddenFor (m => m.CollectionField [i] .Property1). – PanJanek
О, и в MVC нет такой вещи, как «postback». Если вам нужно, вы можете имитировать ее, добавив скрытые поля в вашу форму, но общая идея отличается от MVC, чем в WebForms. – PanJanek