Подтвердить что ты не робот

Использование моделей представления в ASP.NET MVC 3

Я сравнительно недавно рассматриваю модели, и у меня возникают проблемы с их использованием. Здесь одна ситуация, когда мне интересно, что такое лучшая практика...

Я помещаю всю информацию, необходимую для просмотра в модель представления. Вот пример - пожалуйста, простите любые ошибки, это закодировано с верхней части моей головы.

public ActionResult Edit(int id)
{
    var project = ProjectService.GetProject(id);

    if (project == null)
        // Something about not found, possibly a redirect to 404.

    var model = new ProjectEdit();
    model.MapFrom(project); // Extension method using AutoMapper.

    return View(model);
}

Если экран разрешает только редактирование одного или двух полей, когда модель представления возвращается, у нее отсутствует достаточно данных (как и должно быть).

[HttpPost]
public ActionResult Edit(int id, ProjectEdit model)
{
    var project = ProjectService.GetProject(id);

    if (project == null)
        // Something about not found, possibly a redirect to 404.

    try
    {
        if (!ModelState.IsValid)
            return View(model) // Won't work, view model is incomplete.

        model.MapTo(project); // Extension method using AutoMapper.
        ProjectService.UpdateProject(project);
        // Add a message for the user to temp data.

        return RedirectToAction("details", new { project.Id });
    }
    catch (Exception exception)
    {
        // Add a message for the user to temp data.

        return View(model) // Won't work, view model is incomplete.
    }
}

Мое временное решение состоит в том, чтобы воссоздать модель представления с нуля, повторно заполнить ее из модели домена, повторно применить данные формы к ней, а затем продолжить как обычно. Но это делает параметр модели зрения несколько бессмысленным.

[HttpPost]
public ActionResult Edit(int id, ProjectEdit model)
{
    var project = ProjectService.GetProject(id);

    if (project == null)
        // Something about not found, possibly a redirect to 404.

    // Recreate the view model from scratch.
    model = new ProjectEdit();
    model.MapFrom(project); // Extension method using AutoMapper.

    try
    {
        TryUpdateModel(model); // Reapply the form data.

        if (!ModelState.IsValid)
            return View(model) // View model is complete this time.

        model.MapTo(project); // Extension method using AutoMapper.
        ProjectService.UpdateProject(project);
        // Add a message for the user to temp data.

        return RedirectToAction("details", new { project.Id });
    }
    catch (Exception exception)
    {
        // Add a message for the user to temp data.

        return View(model) // View model is complete this time.
    }
}

Есть ли более элегантный способ?

ИЗМЕНИТЬ

Оба ответа верны, поэтому я бы наградил их обоих, если мог. Ног идет в MJ, так как после проб и ошибок я считаю, что его решение было самым скудным.

Я все еще могу использовать помощников, Джимми. Если я добавлю то, что мне нужно отобразить в сумке просмотра (или просмотреть данные), например...

ViewBag.Project= project;

Затем я могу сделать следующее...

@Html.LabelFor(model => ((Project)ViewData["Project"]).Name)
@Html.DisplayFor(model => ((Project)ViewData["Project"]).Name)

Немного взлома, и в некоторых случаях требуется, чтобы модель домена была украшена System.ComponentModel.DisplayNameAttribute, но я уже это делаю.

Мне бы хотелось позвонить...

@Html.LabelFor(model => ViewBag.Project.Name)

Но динамика вызывает проблему в выражениях.

4b9b3361

Ответ 1

После некоторого обучения с ошибкой (ака, это, а затем ненавижу) мой предпочтительный мой подход:

Я использую модели view только для привязки полей ввода. Поэтому в вашем случае, если ваше представление только редактирует два поля, то ваша модель просмотра будет иметь только два свойства. Для данных, необходимых для заполнения представления (раскрывающихся списков, меток и т.д.), Я использую динамический ViewBag.

Я считаю, что отображение вида (то есть заполнение всего, что должно отображаться в представлении), и захват опубликованных значений формы (привязка, проверка и т.д.) - две отдельные проблемы. И я считаю, что смешивание данных, необходимых для заполнения представления, тем, что отправлено назад из представления, становится беспорядочным, и создает именно вашу ситуацию чаще, чем нет. Мне не нравятся частично населенные объекты.

Я не уверен, как это происходит с Automapper (для отображения объекта домена в динамический ViewBag), хотя я его не использовал. Я считаю, что у него есть метод DynamicMap, который может работать? У вас не должно быть проблем с автоматическим отображением опубликованного строго типизированного ViewModel на объект Domain.

Ответ 2

Если я правильно понял, ваша viewmodel, вероятно, очень похожа на вашу сущность домена. Вы упомянули, что viewmodel может вернуться в основном пустым, потому что доступны только определенные поля.

Предполагая, что у вас есть представление, в котором доступно только несколько полей для редактирования (или отображения), это единственные поля, которые вы должны сделать доступными в своей модели viewmodel. Обычно я создаю одну модель представления для каждого представления и позволяю либо контроллеру, либо службе обрабатывать вход пользователя и сопоставлять его с объектом домена после выполнения некоторой проверки.

Здесь поток, касающийся лучших практик для моделей просмотра, которые могут вам пригодиться.

Изменить: Вы также можете принять другую модель просмотра в действии Edit/POST, чем действие Edit/GET. Я считаю, что это должно работать до тех пор, пока модельное связующее может понять это.