Der Aufruf Update mit einer Sammlung von komplexen Datentypen setzen Sie alle nicht gebundenen Werte?

StackOverflow https://stackoverflow.com/questions/1207991

Frage

Ich bin mir nicht sicher, ob dies ein Fehler in der Default Klasse ist oder was. Aber Update ändert sich in der Regel keine Werte des Modells außer denen es eine Übereinstimmung gefunden. Werfen Sie einen Blick auf die folgenden:

[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" });
    // ...
}

Was passiert, ist Update schafft neue Person Objekte, ordnen ihre Namen & Alte Eigenschaften aus den Valueprovider und sie in der Argumentliste setzen <>, die auf den Standardanfang den Rest der Eigenschaften festgelegt machen Wert (zB ID = 0) so was ist hier los?

War es hilfreich?

Lösung

UPDATE: Ich trat durch mvc Quellcode (insbesondere DefaultModelBinder Klasse) und hier ist das, was ich gefunden habe:

Die Klasse bestimmt, wir versuchen, eine Sammlung zu binden, damit es die Methode aufruft: UpdateCollection(...), die eine innere ModelBindingContext schafft, die eine null Model Eigenschaft hat. Danach wird dieser Kontext der Methode BindComplexModel(...) gesendet, der die Model Eigenschaft für null prüft und erstellt ein neue Instanz des Modelltyps, wenn das der Fall ist.

Das ist, was die Werte verursacht zurückgesetzt werden.

Und so wird nur die Werte, die durch die Form / Abfrage-String / Routendaten kommen sind bevölkert, der Rest bleibt in ihrem initialisierten Zustand.

konnte ich nur sehr wenige Änderungen an UpdateCollection(...) dieses Problem zu beheben.

Hier ist die Methode, mit meinen Änderungen:

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;

}

Andere Tipps

Rudi Breedenraed schrieb nur eine ausgezeichnete Post beschreibt dieses Problem und eine sehr hilfreiche Lösung. Er überschreibt die Default und dann, wenn es in einer Sammlung kommt zu aktualisieren, aktualisiert sie eigentlich das Element, anstatt sie neu wie das Standard-MVC Verhalten zu schaffen. Damit Update () und TryUpdateModel () Verhalten steht im Einklang sowohl mit dem Root-Modell und keine Sammlung.

Du hast mir gerade eine Idee in ASP.NET MVC 2 Quellcode zu graben. Ich habe jetzt zwei Wochen lang kämpfen mit diesem. Ich fand heraus, dass Ihre Lösung nicht mit verschachtelten Listen arbeiten. Ich habe einen Haltepunkt in der UpdateCollection Methode, und es wird nie getroffen. Es scheint, wie die Root-Ebene des Modells eine Liste sein muss für diese Methode aufgerufen wird

Das ist kurz gesagt das Modell I have..I auch eine weitere Ebene von allgemeinen Listen haben, aber dies ist nur eine kurze Probe ..

public class Borrowers
{
   public string FirstName{get;set;}
   public string LastName{get;set;}
   public List<Address> Addresses{get;set;}
}

Ich denke, dass ich brauche, tiefer zu graben, um herauszufinden, was los ist.

UPDATE: Die UpdateCollection noch in asp.net MVC 2, aber das Problem mit dem Update oben auf diesem HIER

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top