What Does UpdateModel() Do?

本文关键字:Do Does UpdateModel What | 更新日期: 2023-09-27 18:18:38

通俗地说,UpdateModel()TryUpdateModel()做什么?我似乎找不到(在SO或网络上)任何关于它实际做什么的明确解释(明确的术语),只是人们在使用它时遇到了问题。

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; }
}

What Does UpdateModel() Do?

当你写

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>(); 

如果你不想这样做可以在谷歌上搜索

源代码: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接收(绑定)你所有的提交值,没有得到留给视图模型绑定。

Update模型基本上用于更新现有模型中的新值。你不需要显式地赋值