Как отобразить Модель Представления назад на Модель предметной области в действии POST?

Каждая статья, найденная в Интернете при использовании ViewModels и использовании Автокартопостроителя, дает инструкции "Контроллера-> Представление" отображение направления. Вы берете модель предметной области наряду со всеми Списками выборки в один специализированный ViewModel и передаете его представлению. Это ясно и прекрасно.
Представление имеет форму, и в конечном счете мы находимся в действии POST. Здесь все Образцовые Редакторы связей прибывают в сцену наряду с [очевидно], другой Моделью Представления, которая [очевидно], связана с исходным ViewModel, по крайней мере, в части соглашений о присвоении имен ради привязки и проверки.

Как Вы отображаете его на свою Модель предметной области?

Позвольте ему быть действием вставки, мы могли использовать тот же Автокартопостроитель. Но что, если это было действие обновления? Мы должны получить наш Доменный Объект из Репозитория, обновить, это - свойства согласно значениям в ViewModel, и сохраните в Репозиторий.

ПРИЛОЖЕНИЕ 1 (9-го февраля 2010): Иногда, присвоение свойств Модели недостаточно. Там должен быть принят некоторые меры против Модели предметной области согласно значениям Модели Представления. Т.е. некоторые методы нужно назвать на Модели предметной области. Вероятно, должен быть своего рода уровень Application Service, который стоит между Контроллером и Доменом для обработки Моделей Представления...


Как организовать этот код и куда поместить его для достижения следующих целей?

  • сохраните контроллеры тонкими
  • соблюдайте практику SoC
  • следуйте за Управляемыми Доменом Принципами разработки
  • будьте DRY
  • быть продолженным...
85
задан Anthony Serdyukov 9 February 2010 в 02:36
поделиться

2 ответа

Такие инструменты, как AutoMapper, можно использовать для обновления существующего объекта данными из исходного объекта. Действие контроллера для обновления может выглядеть следующим образом:

[HttpPost]
public ActionResult Update(MyViewModel viewModel)
{
    MyDataModel dataModel = this.DataRepository.GetMyData(viewModel.Id);
    Mapper<MyViewModel, MyDataModel>(viewModel, dataModel);
    this.Repostitory.SaveMyData(dataModel);
    return View(viewModel);
}

Помимо того, что видно в приведенном выше фрагменте:

  • POST-данные для просмотра модели + проверка выполняется в ModelBinder (может быть расширена с помощью пользовательских привязок)
  • Обработка ошибок ( т.е. перехват исключений доступа к данным репозиторием) может выполняться фильтром [HandleError]

Действие контроллера довольно тонкое, и проблемы разделены: проблемы сопоставления решаются в конфигурации AutoMapper, проверка выполняется ModelBinder, а доступ к данным - репозиторием.

7
ответ дан 24 November 2019 в 08:23
поделиться

Я использую интерфейс IBuilder и реализую его с помощью ValueInjecter

public interface IBuilder<TEntity, TViewModel>
{
      TEntity BuildEntity(TViewModel viewModel);
      TViewModel BuildViewModel(TEntity entity);
      TViewModel RebuildViewModel(TViewModel viewModel); 
}

.... (реализация) RebuildViewModel просто вызывает BuildViewModel(BuilEntity(viewModel))

[HttpPost]
public ActionResult Update(ViewModel model)
{
   if(!ModelState.IsValid)
    {
       return View(builder.RebuildViewModel(model);
    }

   service.SaveOrUpdate(builder.BuildEntity(model));
   return RedirectToAction("Index");
}

btw я не пишу ViewModel я пишу Input потому что это намного короче, но это просто не очень важно
. надеюсь это поможет

Обновление: Я использую этот подход сейчас в ProDinner ASP.net MVC Demo App, теперь оно называется IMapper, есть также pdf, где этот подход объясняется подробно

37
ответ дан 24 November 2019 в 08:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: