Когда создаются объекты модели в MVC3 (ASP.NET) - PullRequest
1 голос
/ 15 мая 2011

Попытка понять, когда объекты модели создаются в MVC3:

У меня есть представление для редактирования "Персона";у каждого человека может быть несколько адресов.Я отображаю адреса в сетке в представлении лица.

Это прекрасно работает при отображении лица;У меня есть частичное представление, которое перебирает Person.Addresses и строит таблицу / сетку.

Проблема возникает при создании нового человека: объект person является нулевым, а ссылка Person.Addresses недопустима.

Я уверен, что мне здесь не хватает чего-то довольно фундаментального: поскольку MVC будет (автоматически) создавать новый экземпляр лица после "Сохранить";казалось бы контрпроизводством попытаться создать свой собственный экземпляр объекта, и если бы я это сделал, неясно, как бы я связал его с остальными значениями ввода в форме.

Одно из последних осложнений:список Addresses не является обязательным;совершенно законно вообще не иметь адреса.

Поскольку реляционные данные настолько распространены, для их обработки должно быть более простое решение.Все разъяснения приветствуются!

Ответы [ 2 ]

3 голосов
/ 30 мая 2011

Ответ на этот вопрос заключается в том, что объекты восстанавливаются из данных POST в форме.Это довольно просто, но MVC скрывает так много из того, что происходит, что трудно увидеть, когда вы пытаетесь получить ваши (MVC) подшипники.

Последовательность элементов:

  1. Создать форму со всеми необходимыми полями;использовать скрытые поля для неотображаемых ключей (ID).
  2. Пользователь взаимодействует с веб-страницей;затем нажимает кнопку отправки формы.
  3. Все данные поля помещаются на страницу контроллера.
  4. MVC повторно объединяет данные в объекты класса.
  5. Страница контроллера вызывается с помощьювосстановленный экземпляр класса в качестве формального параметра.

Примечания:

При создании страницы: создается форма с полями для каждой части представляемого объекта.MVC использует скрытые поля для идентификаторов и других неотображаемых данных, а также для правил проверки.
Стоит отметить, что формы создаются (обычно) либо путем перечисления всех свойств объекта на странице _CreateOrEdit.cshtml:

// Edit.cshtml
@model Person

@Html.Partial("_CreateOrEdit", Model)

и

// _CreateOrEdit.cshtml
@model Person

@Html.HiddenFor(model => model.PersonID)

@Html.LabelFor(model => model.first_name, "First Name")
@Html.EditorFor(model => model.first_name)

@Html.LabelFor(model => model.last_name, "Last Name")
@Html.EditorFor(model => model.last_name)

@Html.LabelFor(model => model.favorite_color, "Favorite Color")
@Html.EditorFor(model => model.favorite_color)

//etcetera

или с помощью шаблона для класса (шаблоны должны иметь то же имя, что и класс, который они представляют, и они расположены в папке Views\Shared\EditorTemplates).

Использование страниц шаблона практически идентично предыдущему методу:

// Edit.cshtml
@model Person

@Html.EditorForModel()

и

// Shared\EditorTemplates\Person.cshtml
@model Person

@Html.HiddenFor(model => model.PersonID)

@Html.LabelFor(model => model.first_name, "First Name")
@Html.EditorFor(model => model.first_name)

@Html.LabelFor(model => model.last_name, "Last Name")
@Html.EditorFor(model => model.last_name)

@Html.LabelFor(model => model.favorite_color, "Favorite Color")
@Html.EditorFor(model => model.favorite_color)

//etcetera

Использование метода шаблона позволяет легко добавлять списки (объекта) в форму,Person.cshtml становится:

// Shared\EditorTemplates\Person.cshtml
@model Person

@Html.HiddenFor(model => model.PersonID)

@Html.LabelFor(model => model.first_name, "First Name")
@Html.EditorFor(model => model.first_name)

@Html.LabelFor(model => model.last_name, "Last Name")
@Html.EditorFor(model => model.last_name)

@Html.LabelFor(model => model.favorite_color, "Favorite Color")
@Html.EditorFor(model => model.favorite_color)

@EditorFor( model => model.Addresses )

//etcetera

и

// Shared\EditorTemplates\Address.cshtml
@model Address
@Html.HiddenFor(model => model.AddressID)

@Html.LabelFor(model => model.street, "Street")
@Html.EditorFor(model => model.street)

@Html.LabelFor(model => model.city, "City")
@Html.EditorFor(model => model.city)

//etcetera

MVC будет обрабатывать создание столько записей формы, сколько необходимо для каждого адреса в списке.

POST работаетточно наоборот;Создается новый экземпляр объекта модели, который вызывает конструктор по умолчанию без параметров, а затем MVC заполняет каждое из полей.Списки заполняются путем изменения процесса сериализации @Html.EditorFor( model.List ).Важно отметить, что вы должны убедиться, что ваш класс создает допустимый контейнер для списка в конструкторе, иначе восстановление списка MVC не удастся:

public class Person
{
    public List<Address> Addresses;

    public Person()
    {
        // You always need to create this List object
        Addresses = new List<Address>();
    }

    ...
}

Это покрывает все.За кулисами происходит много всего, но все это можно отслеживать.

Два важных момента, если у вас возникли проблемы с этим:

  1. Убедитесь, что у вас есть @Html.HiddenFor(...) для всего, что нужно «пережить» поездку обратно на сервер.
  2. Используйте Fiddler или HTTPLiveHeaders (плагин Firefox) для проверки содержимого данных POST.Это позволит вам проверить, какие данные отправляются обратно, чтобы воссоздать новый экземпляр класса.Я неравнодушен к Fiddler, так как вы можете использовать его с любым браузером (и он показывает данные формы особенно хорошо).

И еще один момент: есть хорошая статья о динамическом добавлении / удалении элементов изсписок с MVC: http://jarrettmeyer.com/post/2995732471/nested-collection-models-in-asp-net-mvc-3 Это хорошая статья для работы - и да, она работает с MVC3 и Razor.

0 голосов
/ 15 мая 2011

Адреса, которые я предполагаю, находятся в таблице, а не фактические элементы ввода и, вероятно, просто

info ?Если это так, то они не будут созданы, так как данные не отправляются обратно на сервер.Вы должны создать эти данные с элементами, которые будут отправлены обратно, чтобы они были сопоставлены (по имени) с их свойствами.Связыватель модели будет создавать экземпляры объектов и передавать их вашему контроллеру при обратной передаче, если он сможет найти элементы с должным именем именованной формы (или строки запроса).
...