Что делает UpdateModel ()? - PullRequest
       25

Что делает UpdateModel ()?

11 голосов
/ 22 декабря 2011

С точки зрения непрофессионала, что делает UpdateModel(), а также TryUpdateModel()?Кажется, я не могу найти (в SO или в Интернете) какого-либо четкого объяснения того, что он на самом деле делает (в ясных терминах), просто у людей, имеющих проблемы с его использованием.

IntelliSense VisualStudio мне тоже не помогает.Причина, по которой я спрашиваю, заключается в том, что, скажем, если у меня есть это в моем контроллере:

[HttpPost]
public ActionResult Index( UserViewModel vm, FormCollection form)
{    
  var statesCheckBoxes = form["StatesList"];       

  vm.BA.StatesTraveledTo = statesCheckBoxes.Split(',').ToList<string>();

  return View(vm);
}

Разве я не обновляю свою модель, установив vm.BA.StatesTraveledTo?Почему мне нужно запустить UpdateModel?Кроме того, когда я на самом деле пытаюсь сделать следующее:

[HttpPost]
public ActionResult Index( UserViewModel vm, FormCollection form)
{    
  var statesCheckBoxes = form["StatesList"];       

  vm.BA.StatesTraveledTo = statesCheckBoxes.Split(',').ToList<string>();

  UpdateModel(vm); // IS THIS REDUNDANT TO THE PREVIOUS LINE?

  return View(vm);
}

Ничего не происходит в том, что, когда я проверяю значение ModelState (после запуска UpdateModel ()), я не вижу ничего, указывающегочто-нибудь изменилось.Я не вижу новый ключ в словаре ModelState.

Действительно растерян.Спасибо!

Редактировать:

Отправка исходного кода для классов ViewModel и Model:

public class UserViewModel
{
  public BankAccount BA { get; set; }
}

public class BankAccount
{
  public Person User { get; set; }
  public List<string> StatesTraveledTo { get; set; }
}

public class Person
{
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public int Age { get; set; }
}

Ответы [ 3 ]

7 голосов
/ 22 декабря 2011

что происходит, когда вы пишете

public ActionResult Index( UserViewModel vm)
{    }

и когда вы проверяете в ActionResult, вы обнаруживаете, что vm содержит значения, которые вы опубликовали в представлении.это связано с тем, что mvc направляет связыватель модели извлекать значения из различных источников (коллекция форм, значения маршрута, строка запроса и т. д.) и заполнять значения вашей модели.Но чтобы это произошло, ключи формы должны соответствовать названию свойств в вашей модели, и если это так, ваша модель заполнена правильно.Теперь мы подошли к актуальному вопросу: что делает UpdateModel?простой ответ - не что иное, как привязка к модели.Разница только в том, что вы называете это явно.Вышеприведенное ActionResult можно переписать так же, как и с помощью UpdateModel

Public ActionResult Index ()
{
   UserViewModel vm = new UserViewModel();
   UpdateModel(vm);// it will do same thing that was previously handled automatically by mvc
}

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

vm.BA.StatesTraveledTo = statesCheckBoxes.Split(',').ToList<string>(); 

, и если вы не хотите делать этовещь проверить это поиск в Google

2 голосов
/ 22 декабря 2011

Вот исходный код: http://aspnet.codeplex.com/SourceControl/changeset/view/72551#266451

Это довольно просто,

    protected internal bool TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties, IDictionary<string, ValueProviderResult> valueProvider) where TModel : class {
        if (model == null) {
            throw new ArgumentNullException("model");
        }
        if (valueProvider == null) {
            throw new ArgumentNullException("valueProvider");
        }

        Predicate<string> propertyFilter = propertyName => BindAttribute.IsPropertyAllowed(propertyName, includeProperties, excludeProperties);
    IModelBinder binder = Binders.GetBinder(typeof(TModel));

    ModelBindingContext bindingContext = new ModelBindingContext() {
        Model = model,
        ModelName = prefix,
        ModelState = ModelState,
        ModelType = typeof(TModel),
        PropertyFilter = propertyFilter,
        ValueProvider = valueProvider
    };
    binder.BindModel(ControllerContext, bindingContext);
    return ModelState.IsValid;
}

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

Просто предположение, но вы можете получить странные результаты, потому что вы делаете вещи нетипичным образом. Подпись вашего действия:

public ActionResult Index( UserViewModel vm, FormCollection form)

принимает UserViewModel И FormCollection. Обычно люди делают одно или другое (на самом деле FormCollection в наше время довольно редок). Опять же, я ухожу из памяти, но я думаю, что UpdateModel ничего не делает, потому что эти значения уже связаны. Если оно пустое, то, возможно, это потому, что FormCollection получает (связывает) все ваши значения submittd, и ничто не остается для привязки модели представления.

0 голосов
/ 22 декабря 2011

Обновление модели в основном используется для обновления новых значений в существующей модели.вам не нужно присваивать значение явно.

...