我不确定这是否是DefaultModelBinder类中的错误或者是什么。 但UpdateModel通常不会更改模型的任何值,除了它找到匹配的值。 看看以下内容:
[AcceptVerbs(HttpVerbs.Post)]
public ViewResult Edit(List<int> Ids)
{
// Load list of persons from the database
List<Person> people = GetFromDatabase(Ids);
// shouldn't this update only the Name & Age properties of each Person object
// in the collection and leave the rest of the properties (e.g. Id, Address)
// with their original value (whatever they were when retrieved from the db)
UpdateModel(people, "myPersonPrefix", new string[] { "Name", "Age" });
// ...
}
UpdateModel会创建新 Person对象,并指定其名称&amp;来自ValueProvider的Age属性并将它们放在参数List&lt;&gt;中,这使得其余属性设置为其默认初始值(例如Id = 0) 那么这里发生了什么?
答案 0 :(得分:9)
<强>更新强>
我介绍了mvc源代码(特别是DefaultModelBinder
类),这是我发现的:
该类确定我们正在尝试绑定一个集合,因此它调用方法:UpdateCollection(...)
,它创建一个具有ModelBindingContext
null
属性的内部Model
。然后,将该上下文发送到方法BindComplexModel(...)
,该方法检查Model
的{{1}}属性并创建模型类型的 new 实例(如果是这种情况) 。
这就是导致重置值的原因。
因此,只填充通过表单/查询字符串/路由数据的值,其余值保持其初始化状态。
我能够对null
进行很少的更改来解决此问题。
以下是我的更改方法:
UpdateCollection(...)
}
答案 1 :(得分:4)
Rudi Breedenraed刚刚写了一篇很好的post 来描述这个问题,这是一个非常有用的解决方案。他重写了DefaultModelBinder,然后当它遇到要更新的集合时,它实际上更新了项目,而不是像默认的MVC行为那样创建它。有了这个,UpdateModel()和TryUpdateModel()行为与根模型和任何集合都是一致的。
答案 2 :(得分:1)
您刚刚给我一个挖掘ASP.NET MVC 2源代码的想法。 我已经在这两个星期里苦苦挣扎了。我发现您的解决方案不适用于嵌套列表。我在UpdateCollection方法中放了一个断点,它永远不会被击中。似乎模型的根级别需要成为此方法的列表
这就是我所拥有的模型。我还有一个级别的通用列表,但这只是一个快速的样本..
public class Borrowers
{
public string FirstName{get;set;}
public string LastName{get;set;}
public List<Address> Addresses{get;set;}
}
我想,我需要深入挖掘以了解发生了什么。
更新: UpdateCollection仍在asp.net mvc 2中调用,但上面修复的问题与此HERE
有关。