用外行的话说,UpdateModel()和TryUpdateModel()都是做什么的?我似乎找不到(在如此或网络上)任何清晰的解释,它实际上做什么(以明确的术语),只是有问题的人使用它。
VisualStudio的intellisense也帮不了我。我问这个问题的原因是,比如说,如果我的控制器里有这个:
[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; }
}发布于 2011-12-22 11:08:48
当你写的时候会发生什么
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>(); 如果你不想做这种事,检查一下这个谷歌搜索
发布于 2011-12-22 06:57:43
下面是它的源代码: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接收(绑定)了所有提交的值,而没有一个视图模型被绑定到。
发布于 2011-12-22 07:00:17
Update模型基本上用于更新现有模型中的新值。您不需要显式地赋值。
https://stackoverflow.com/questions/8600239
复制相似问题