MISE À JOUR: je suis entré dans le code source mvc (en particulier DefaultModelBinder
de classe) et voici ce que je trouve:
La classe détermine que nous essayons de lier une collection de sorte qu'il appelle la méthode: UpdateCollection(...)
qui crée une propriété interne ModelBindingContext
qui a une propriété null
Model
. Ensuite, ce contexte est envoyé à la méthode BindComplexModel(...)
qui vérifie la propriété Model
pour null
et crée une nouvelle instance du type de modèle si tel est le cas.
C'est ce qui provoque la réinitialisation des valeurs. Ainsi, seules les valeurs qui traversent le formulaire/chaîne de requête/données de route sont remplies, le reste reste dans son état initialisé.
J'ai été en mesure de faire très peu de changements à UpdateCollection(...)
pour résoudre ce problème.
Voici la méthode avec mes changements:
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;
}
est-ce vrai aussi pour MVC 3? – Vidar
@Vidar Oui, j'ai peur. – nfplee