MVC - Частично обновить модель в представлении - PullRequest
0 голосов
/ 17 мая 2011

Вот сценарий: у меня есть объект User, подобный этому:

 public class User : BaseEntity<User>, IAggregateRoot
 {
    public virtual string Name { get; set; }
    public virtual string Username { get; set; }
    public virtual string Password { get; set; }
    public virtual string SecretQuestion { get; set; }
    public virtual string SecretAnswer { get; set; }
    public virtual DateTime LastLogin { get; set; }
 }

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

Является ли лучшая стратегия для создания пользовательской модели представления, и будет ли nhibernate справляться с этим, когда я пытаюсь обновить пользовательский объект с нулевым полем LastLogin?

Заранее спасибо.

EDIT

Примерно так:

public class UserViewModel
{
  public string Name {get;set;}
  public string UserName {get;set;}
  public string Password {get;set;}
  public string SecretQuestion {get;set;}
  public string SecretAnswer {get;set;}
}

А потом редактирование:

public ActionResult Edit(int id)
{
  return View(_userRepository.FindById(id));
}

[HttpPost]
public ActionResult Edit(int id, UserViewModel userViewModel)
{
  try
  {

    //Not sure how to update the model 
    //with the view Model and save.

    _userRepository.Update(????);
    return RedirectToAction("Index");
  }
  catch
  {
    return View();
  }
}

Ответы [ 3 ]

8 голосов
/ 17 мая 2011

Хорошим подходом является создание UserViewModel только с теми свойствами, которые вы хотите отобразить / обновить. Не сообщайте nHibernate о модели представления. Затем, когда изменения отправляются обратно на контроллер, вы извлекаете фактический объект User из nHibernate, обновляете его свойства из модели представления и затем сохраняете его обратно в базу данных.

Обновление

Примерно так:

[HttpPost]
public ActionResult Edit(int id, UserViewModel userViewModel)
{
  try
  {
    User model = _userRepository.FindById(id);

    model.Name = userViewModel.Name;
    model.Username = userViewModel.Username;
    model.Password = userViewModel.Password;
    model.SecretQuestion = userViewModel.SecretQuestion;
    model.SecretAnswer = userViewModel.SecretAnswer;

    _userRepository.Update(model);
    return RedirectToAction("Index");
  }
  catch
  {
    return View();
  }
}

В проекте, над которым я недавно работал, я создал класс ViewModelBase, который включает методы, которые отображают свойства из модели домена в модель представления и обратно на основе соответствия имени и типа свойства. Все мои модели представлений являются производными от ViewModelBase.

Существуют и другие инструменты, такие как AutoMapper , которые делают подобные вещи и многое, многое другое.

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

Я добавляю другой ответ, потому что есть другой, совершенно другой подход.

Вы можете просто использовать объект User в своем представлении, а затем использовать TryUpdateModel, чтобы указать свойства дляОбновление в модели.Вам не обязательно нужна модель представления в этом случае.Вы можете использовать один, если хотите, но вам не нужно.

Тогда действие Post будет выглядеть примерно так:

[HttpPost]
public ActionResult Edit(int id)
{
  try
  {
    User model = _userRepository.FindById(id);
    var propertiesToUpdate = new string[] { "Name", 
                                            "Username", 
                                            "Password", 
                                            "SecretQuestion", 
                                            "SecretAnswer" };

    if (TryUpdateModel(model, propertiesToUpdate)) {
      _userRepository.Update(model);
      return RedirectToAction("Index");
    }
  }
  catch
  {
    // Handle exceptions however you want.
  }
  return View();
}

Массив строк представляет собой белый список свойств, которые необходимо обновить в модели, и контроллер пытается обновить значения изформа почтовых данных (и других источников).Поскольку LastLogin отсутствует в строковом массиве, он не будет затронут в обновлении модели.

0 голосов
/ 11 октября 2013

Я работаю над техникой, в которой я создаю пользовательскую производную DefaultModelBinder.Он работает в том же духе, что и подход с использованием белого списка, опубликованный @AndrewCooper, но с изюминкой.

В моем подходе я придерживаюсь одной большой сигнальной ViewModel, которая может иметь множество частичных просмотров, пытающихся обновитьЭто.Белый список, в моем случае, - это критические поля идентификации объекта , необходимые для информирования ViewModel о том, как он может автоматически загружаться из репозитория, поэтому ожидается, что частичные представления содержат ТОЛЬКО поля, которые онизаботиться о и достаточном количестве скрытых полей для уточнения идентичности объекта , если это не сразу видно из маршрута или чего-либо еще.

Таким образом, во время фазы связывания модели POST идентичностьполя привязываются первыми (таким образом, «загрузка» запускается для немедленного обновления модели из БД), а после завершения процесса связывания вы фактически «слили» объект, извлеченный из БД, с данными, предоставленными пользователем... и вдобавок к этому (при условии, что вы придерживались соглашений MVC) теперь он прошел проверку.

Это позволяет мне придерживаться простого метода контроллера из учебника .. что-то вроде ..

  Public Function Edit(id As Integer, workOrder as MergedWorkOrderModel) As ActionResult
    If ModelState.IsValid Then
        /* save model, send success messaging into ViewBag, etc */
        workOrder.Save("ServiceUrl")
        workOrder.Load("ServiceUrl")
        ViewBag.SuccessMessage = String.Format("Order {0} saved successfully!", workOrder.Id)
        Return View(workOrder)
    Else
        /* return user model to fix errors */
        ViewBag.ErrorMessage = String.Format("Order {0} did not save.", workOrder.Id)
        Return View(workOrder)
    End If
  End Function

Теоретически, я мог бы указать все свои различные взгляды на этот же метод - потому что это не важно, гдеПользовательские данные получены из .. все они объединяются с последними из БД, проверяются и сохраняются одинаково.

Больше информации на моем посте StackOverflow

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...