调用的UpdateModel具有复杂数据类型的集合重置所有非约束值? [英] Calling UpdateModel with a collection of complex data types reset all non-bound values?

查看:165
本文介绍了调用的UpdateModel具有复杂数据类型的集合重置所有非约束值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道这是否是在DefaultModelBinder类或什么错误。
但通常的UpdateModel不改变,除了它找到了一个匹配的那些模型的任意值。
在下面一起来看看:

I'm not sure if this is a bug in the DefaultModelBinder class or what. But UpdateModel usually doesn't change any values of the model except the ones it found a match for. Take a look at the following:

[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对象,分配他们的姓名和放大器;从ValueProvider时代性,并把它们在参数列表&LT;>,这使得设置为默认的初始值的属性的其余部分(例如ID = 0)
那么,什么是怎么回事?

What happens is UpdateModel creates new Person objects, assign their Name & Age properties from the ValueProvider and put them in the argument List<>, which makes the rest of the properties set to their default initial value (e.g. Id = 0) so what is going on here?

推荐答案

更新:
我通过MVC源码code(尤其是 DefaultModelBinder 类),并在这里踩是我发现:

UPDATE: I stepped through mvc source code (particularly DefaultModelBinder class) and here is what I found:

类决定了我们正在努力使其调用方法绑定集合: UpdateCollection(...)这将创建一个内部 ModelBindingContext 具有 模式属性。此后,这种情况下被发送到检查模式属性<$ c中的方法 BindComplexModel(...) $ C>空并创建一个模型类型的实例,如果是这样的情况。

The class determines we are trying to bind a collection so it calls the method: UpdateCollection(...) which creates an inner ModelBindingContext that has a null Model property. Afterwards, that context is sent to the method BindComplexModel(...) which checks the Model property for null and creates a new instance of the model type if that is the case.

这是什么原因造成的值复位。

That's what causes the values to be reset.

所以,填充只有通过形式/查询字符串/路由数据里的值,其余保持其初始状态。

And so, only the values that are coming through the form/query string/route data are populated, the rest remains in its initialized state.

我能够做很少修改 UpdateCollection(...)来解决这个问题。

I was able to make very few changes to UpdateCollection(...) to fix this problem.

下面是我的变化方法:

internal object UpdateCollection(ControllerContext controllerContext, ModelBindingContext bindingContext, Type elementType) {
IModelBinder elementBinder = Binders.GetBinder(elementType);

// build up a list of items from the request
List<object> modelList = new List<object>();
for (int currentIndex = 0; ; currentIndex++) {
	string subIndexKey = CreateSubIndexName(bindingContext.ModelName, currentIndex);
	if (!DictionaryHelpers.DoesAnyKeyHavePrefix(bindingContext.ValueProvider, subIndexKey)) {
		// we ran out of elements to pull
		break;
	}
	// **********************************************************
	// The DefaultModelBinder shouldn't always create a new
	// instance of elementType in the collection we are updating here.
	// If an instance already exists, then we should update it, not create a new one.
	// **********************************************************
	IList containerModel = bindingContext.Model as IList;
	object elementModel = null;
	if (containerModel != null && currentIndex < containerModel.Count)
	{
	    elementModel = containerModel[currentIndex];
	}
     //*****************************************************
	ModelBindingContext innerContext = new ModelBindingContext() {
		Model = elementModel, // assign the Model property
		ModelName = subIndexKey,
		ModelState = bindingContext.ModelState,
		ModelType = elementType,
		PropertyFilter = bindingContext.PropertyFilter,
		ValueProvider = bindingContext.ValueProvider
	};
	object thisElement = elementBinder.BindModel(controllerContext, innerContext);

	// we need to merge model errors up
	VerifyValueUsability(controllerContext, bindingContext.ModelState, subIndexKey, elementType, thisElement);
	modelList.Add(thisElement);
}

// if there weren't any elements at all in the request, just return
if (modelList.Count == 0) {
	return null;
}

// replace the original collection
object collection = bindingContext.Model;
CollectionHelpers.ReplaceCollection(elementType, collection, modelList);
return collection;

}

这篇关于调用的UpdateModel具有复杂数据类型的集合重置所有非约束值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆