Je ne suis pas sûr que ceci est un bogue dans la classe de typefrinder ou quoi. Mais UpdateTemodel ne modifie généralement aucune valeur du modèle, à l'exception de celles qu'il a trouvé une correspondance. Jetez un coup d'œil à ce qui suit:
[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" }); // ... }
3 Réponses :
La classe détermine que nous essayons de lier une collection afin qu'elle appelle la méthode: C'est ce qui provoque la réinitialisation des valeurs. p> et donc, seules les valeurs qui traversent les données de la chaîne de formulaire / de la chaîne / de la route sont peuplées, le reste reste dans son état initialisé. P> J'ai pu faire très peu de Modifications apportées à Voici la méthode avec mes modifications: p> defaultModelbinder Code> Classe) et voici ce que j'ai trouvé:
UpdateCollection (. ..) code> qui crée un
modelbindingcontext code> qui comporte un
null code>
modèle code> propriété. Ensuite, ce contexte est envoyé à la méthode
bindcomplexmodel (...) code> qui vérifie la propriété
modèle code> pour
null code> et crée une nouvelle nouvelle strong> instance du type de modèle si tel est le cas. P>
UpdateCollection (...) code> pour corriger ce problème. p>
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;
Vous venez de me donner une idée de creuser dans le code source ASP.NET MVC 2. J'ai eu du mal avec cela pendant deux semaines maintenant. J'ai découvert que votre solution ne fonctionnera pas avec des listes imbriquées. Je mets un point d'arrêt dans la méthode UpdateCollection et il n'est jamais frappé. Il semble que le niveau de racine du modèle doit être une liste de cette méthode à appeler
Ceci est bref le modèle que j'ai..J'ai aussi un niveau de plus de listes génériques, mais il s'agit simplement d'un échantillon rapide. . P>
public class Borrowers { public string FirstName{get;set;} public string LastName{get;set;} public List<Address> Addresses{get;set;} }
Rudi Breeenraded vient d'écrire un excellent POST a> décrivant ce problème et une solution très utile. Il remplace la valeur par défautModelbinder puis lorsqu'il s'agit d'une collection à la mise à jour, elle met à jour l'article au lieu de la créer de nouveau comme le comportement MVC par défaut. Avec ce comportement, UpdateModel () et TryPDaTemodel () est compatible avec le modèle racine et toutes les collections. P>