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

Другие вопросы по тегам