MVC, передача значений из нескольких частичных представлений на странице
У меня проблема, когда я пытаюсь передать значения обратно со своей страницы, которая дважды содержит одно и то же частичное представление. Мое определение класса как ниже:
public class Account : IEntity
{
public decimal CurrentBalance { get; set; }
public List<Person> AccountHolders { get; set; }
//to get round the non-existing enum support in EF4.3 wrap enum to int
public int StatusValue { get; set; }
public AccountStatus Status { get { return (AccountStatus)StatusValue; } set { StatusValue = (int) value; } }
public DateTime AccountOpenDate { get; set; }
public DateTime AccountCloseDate { get; set; }
public DateTime AccountSuspensionDate { get; set; }
}
У него есть список лиц, для которых я сделал частичное представление (для одного).
<fieldset>
<legend>Person</legend>
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Age)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Age)
@Html.ValidationMessageFor(model => model.Age)
</div>
</fieldset>
На странице "Создание учетной записи" я включил 2 части частичных представлений, которые я создал, как показано ниже.
<div id="Person1">
@Html.Partial("_CreateAccountHolder" )
</div>
<div id="Person2">
@Html.Partial("_CreateAccountHolder")
</div>
Когда я смотрю на то, что публикуется обратно, оно содержит значения (имя и возраст как свойства Person), которые я вставляю в значения формы страницы, и у меня есть их количество, как и ожидалось: CurrentBalance=19&Status=Closed&AccountOpenDate=12%2F12%2F2012& Имя = Mustafa& Возраст =20& Имя = софия & Возраст =20&AccountCloseDate=12%2F12%2F2012&AccountSuspensionDate=12%2F12%2F2012
Но когда я смотрю на метод create на моем контроллере, я вижу список AccountHolder как нулевой. Я пробовал с различными подписями... public ActionResult Create(Account personalaccount, Person [] accountHolders) public ActionResult Create(Account personalaccount, Список accountHolders)
Если у меня только одно частичное представление Person и мой контроллер подобен этому, я могу видеть объект Person правильно привязанным. public ActionResult Create (Личная учетная запись, Персональная учетная запись пользователя)
Любые идеи относительно того, где я иду не так?
3 ответа
Если я правильно понимаю ваш сценарий, одним из способов достижения этого является использование шаблонов редактора вместо частичных представлений. Я должен немного написать о них здесь:
codenodes.wordpress.com - Шаблоны редактора MVC3
Чтобы создать шаблон редактора:
- если у вас еще нет папки с именем Editor Templates в веб-проекте вашего решения, создайте ее в папке Views\Shared.
- добавьте новое частичное представление и назовите его так же, как модель, которую вы отображаете, в вашем случае Person, так что вы бы назвали это Person.cshtml (я знаю, что частичные представления должны начинаться с подчеркивания "_", но для редактора Шаблон должен быть назван так же, как модель).
- вставьте код из вашего частичного представления "_CreateAccountHolder" в новый шаблон редактора Person.cshtml.
- на странице "Создать" создайте свой список AccountHolders следующим образом:
<div id="People"> @Html.EditorFor(x => x.AccountHolders) </div>
Если вам нужно иметь отдельные элементы div для каждого персонажа, вы можете добавить их в свой шаблон редактора. Преимущество шаблонов редактора заключается в том, что вам нужен только один вызов шаблона, даже если в вашем списке несколько объектов Person - не нужно зацикливаться или делать что-то подобное, поскольку шаблон автоматически отображает каждый объект Person. Он также правильно называет поле, поэтому он должен публиковать что-то вроде этого, если, например, у вас есть 2 объекта Person в вашей коллекции:
AccountHolders[0].Name AccountHolders[0].Age AccountHolders[1].Name AccountHolders[1].Age
Вот код для вашего шаблона редактора:
@model Person
<fieldset>
<legend>Person</legend>
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Age)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Age)
@Html.ValidationMessageFor(model => model.Age)
</div>
</fieldset>
Сначала вы должны создать CreateAccountModel с двумя экземплярами AccountModel, что-то вроде:
public class CreateAccountModel
{
public Account Person1 { get; set; }
public Account Person2 { get; set; }
}
Затем, когда вы добавляете свои частичные представления, вы должны передать им отдельные модели, например:
<div id="Person1">
@Html.Partial("_CreateAccountHolder", Model.Person1)
</div>
<div id="Person2">
@Html.Partial("_CreateAccountHolder", Model.Person2)
</div>
Теперь MVC автоматически префиксирует все поля учетной записи с PersonX, поэтому все поля будут уникальными.
В качестве альтернативы вы можете указать префиксы вручную при добавлении частичных представлений:
{
var prefixData = new ViewDataDictionary { TemplateInfo = { HtmlFieldPrefix = "Person1" } };
Html.RenderPartial("_CreateAccountHolder", new ViewDataDictionary(prefixData));
}
Я понял мою проблему после прочтения [http://stackru.com/questions/653514/asp-net-mvc-model-binding-an-ilist-parameter][1] Размещение двух частичных представлений одного типа привело к возврату представления Имя и возраст пары ничем не отличаются от первой и второй пары. Я изменил парциальное представление, как показано ниже, но мне это не нравится...
<div class="editor-field">
@Html.TextBox("person[0].Name", "")
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-field">
@Html.TextBox("person[0].Age", "")
@Html.ValidationMessageFor(model => model.Age)
</div>
<div class="editor-field">
@Html.TextBox("person[1].Name", "")
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-field">
@Html.TextBox("person[1].Age", "")
@Html.ValidationMessageFor(model => model.Age)
</div>
Теперь он выполняет обратную передачу, как показано ниже, и я могу прочитать IList в моем контроллере.
CurrentBalance = 19 & Статус = Закрыто &AccountOpenDate=12%2F12%2F2012 и человек%5B0%5D.Name= Mustafa& человек%5B0%5D.Age=19& человек%5B1%5D.Name= софия & человек%5B1%5D.Age=20&AccountCloseDate=10%2F10%2F2012&AccountSuspensionDate=12%2F12%2F2012