MVC4 - привязка модели с частичным представлением во время отправки
У меня есть модель представления, у которой есть еще одна дочерняя модель для частичного просмотра (ниже).
public class ExamResultsFormViewModel
{
public PreliminaryInformationViewModel PreliminaryInformation { get; set; }
public string MemberID { get; set; }
public string MemberName { get; set; }
public int PatientID { get; set; }
public string ConfirmationID { get; set; }
public bool IsEditable { get; set; }
#region Select Lists
public SelectList ProviderOptions { get; set; }
#endregion
}
public class PreliminaryInformationViewModel
{
public string ProviderName { get; set; }
public string ProviderID { get; set; }
public string ServiceLocation { get; set; }
}
Эта модель представления PreliminaryInformationViewModel также используется в качестве дочерних моделей в другой модели представления, поскольку эта предварительная информация может быть обновлена на разных страницах.
Итак, я создал эту предварительную информацию как отдельную часть и включил ее на другие страницы.
@{Html.RenderPartial("_PreliminaryInformation", Model.PreliminaryInformation);}
Внутри частичного
@model Web.Models.Preliminary.PreliminaryInformationViewModel
<div>
@Html.TextBoxFor(x => x.DateOfService })
</div>
Но проблема заключается в том, что эта предварительная модель всегда равна нулю из-за того, что атрибут имени HTML всегда отображается как
но когда я передаю родительскую модель частичной, как показано ниже.
@model Web.Models.Exam.ExamResultsFormViewModel
<div>
@Html.TextBoxFor(x => x.PreliminaryInformation.DateOfService })
</div>
Теперь элемент HTML создается как
<input type = 'text' name='PreliminaryInformation.DateOfService.DateOfService' id='PreliminaryInformation.DateOfService'>
и он правильно связывается во время отправки.
Я понимаю, что MVC привязывает значение элемента на основе значения атрибута name, но для второй реализации мне потребуется создать несколько частичных для каждой страницы, что мне не нравится.
До сих пор я не мог найти решение для работы с первой версией, есть способ, которым я могу связать привязку значения предварительной информационной модели во время отправки с первой реализацией.
Ответы
Ответ 1
Я знаю, что немного поздно, но это может кому-то помочь
Если у вас сложная модель, вы все равно можете передать ее в частичное использование:
@Html.Partial("_YourPartialName", Model.Contact, new ViewDataDictionary()
{
TemplateInfo = new TemplateInfo()
{
HtmlFieldPrefix = "Contact"
}
})
где я определил модель со свойством "Контакт". Теперь, что делает HtmlFieldPrefix, это добавляет привязку свойства для каждой модели, "чтобы связыватель модели мог найти родительскую модель"
Об этом есть сообщение в блоге: http://www.cpodesign.com/blog/bind-partial-view-model-binding-during-submit/
Привязка .NET Core 2
В .NET Core 2 и MVC ответ выше не будет работать, свойство больше не может быть установлено.
Как бы то ни было, решение очень похоже.
@{ Html.ViewData.TemplateInfo.HtmlFieldPrefix = "Contact"; }
@await Html.PartialAsync("_YourPartialName", Model.Contact)
после того, как вы сможете отправить свою модель, она снова свяжется.
надеюсь, это поможет
Ответ 2
Вам нужно создать шаблон редактора для PreliminaryInformationViewModel
, чтобы заменить частичный вид, а затем вызвать с помощью Html.EditorFor( m => m.PreliminaryInformation )
. Ссылка это решение. Создание шаблона должно быть таким же простым, как перемещение частичного представления в каталог Views/Shared/EditorTemplates. Html.EditorFor(...)
будет автоматически использовать этот шаблон на основе типа, который вы передаете в качестве модели (в данном случае PreliminaryInformationViewModel
)
Ответ 3
Вы можете добавить HtmlFieldPrefix в начало частичного просмотра:
@{
ViewData.TemplateInfo.HtmlFieldPrefix = "Contact";
}
Это тот же подход, что и описанный @cpoDesign, но это означает, что вы можете сохранить префикс в частичном представлении, если вам нужно это сделать.
Ответ 4
Я также столкнулся с этой проблемой. Я объясню свое решение, используя ваш код. Я начал с этого:
@{
Html.RenderPartial("_PreliminaryInformation", Model.PreliminaryInformation);
}
Действие, соответствующее сообщению http, искало родительскую модель. Сообщение http правильно подавало форму, но не было ссылки на ребенка, частичного родительского частичного. Представленные значения из дочернего элемента были проигнорированы, и соответствующее дочернее свойство оставалось нулевым.
Я создал интерфейс, IPreervedInfoCapable, который содержал определение для дочернего типа, например:
public interface IPreliminaryInfoCapable
{
PreliminaryInformationViewModel PreliminaryInformation { get; set; }
}
Я сделал свою родительскую модель реализацией этого интерфейса. Затем мое частичное представление использует интерфейс вверху в качестве модели:
@model IPreliminaryInfoCapable
Наконец, мое родительское представление может использовать следующий код, чтобы передать себя дочернему частицу:
@{
Html.RenderPartial("ChildPartial", Model);
}
Тогда дочерний частичный может использовать дочерний объект, например:
@model IPreliminaryInfoCapable
...
@Html.LabelFor(m => m.PreliminaryInformation.ProviderName)
etc.
Все это правильно заполняет родительскую модель после HTTP-сообщения соответствующим действием.
Ответ 5
Быстрый совет: при вызове метода EditorFor вы можете указать имя шаблона в качестве параметра метода Html.EditorFor. В качестве альтернативы, соглашения об именах могут быть вашим другом; просто убедитесь, что имя файла шаблона вашего редактора точно совпадает с именем типа свойства модели
то есть. тип свойства модели 'CustomerViewModel' = > 'CustomerViewModel.cshtml' шаблон редактора.
Ответ 6
Пожалуйста, сделайте следующие изменения на своей частичной странице. поэтому он будет поставляться с вашей родительской моделью
//Parent Page
@{Html.RenderPartial("_PreliminaryInformation", Model.PreliminaryInformation);}
//Partial Page
@model Web.Models.Preliminary.PreliminaryInformationViewModel
@using (Html.BeginCollectionItem("PreliminaryInformation", item.RowId, true))
{
<div>
@Html.TextBoxFor(x => x.DateOfService })
</div>
}
Ответ 7
Для .net core 2 и mvc используйте do как ниже:
@{
Html.ViewData.TemplateInfo.HtmlFieldPrefix = "Contact";
}
@await Html.PartialAsync("_YourPartialViewName", Model.Contact)