2009-04-03 15 views
7

Ich versuche, ein benutzerdefiniertes Modellbinder zu schreiben, aber ich habe große Schwierigkeit, herauszufinden, wie komplexe komplexe Objekte gebunden werden.Benutzerdefiniertes Modellbinder für komplexe zusammengesetzte Objekte HELP

ist dies die Klasse I zu binden bin versucht:

public class Fund 
{ 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public List<FundAllocation> FundAllocations { get; set; } 
} 

und das ist, wie mein Versuch, das benutzerdefinierte Binder Schreiben wie folgt aussieht:

public class FundModelBinder : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     throw new NotImplementedException(); 
    } 

    public object GetValue(ControllerContext controllerContext, string modelName, Type modelType, ModelStateDictionary modelState) 
    { 
     var fund = new Fund(); 

     fund.Id = int.Parse(controllerContext.HttpContext.Request.Form["Id"]); 
     fund.Name = controllerContext.HttpContext.Request.Form["Name"]; 

     //i don't know how to bind to the list property :(
     fund.FundItems[0].Catalogue.Id = controllerContext.HttpContext.Request.Form["FundItem.Catalogue.Id"]; 
     return fund; 
    } 
} 

Irgendwelche Ideen

danke Tony

+0

Ich habe gerade eine Frage gestellt und dann schließlich eine Lösung für diese Art von Problem gefunden. Für diejenigen, die interessiert sind, können Sie den folgenden Link überprüfen: [http://stackoverflow.com/questions/1077481/how-doi-i-pass-a-dictionary-as-a-parameter-to-an-actionresult -method-from-jquery-a] (http://stackoverflow.com/questions/1077481/how-doi-i-pass-a-dictionary-as-a-parameter-to-an-actionresult-method-from- jquery-a) –

Antwort

3

Ich habe zu viel auf genau dieses s ausgegeben ame Sache in letzter Zeit!

Ohne Ihr HTML-Formular zu sehen, vermute ich, dass es nur die Ergebnisse der Auswahl aus einer Multi-Select-Liste oder etwas zurückgibt? Wenn dies der Fall ist, gibt Ihr Formular nur eine Reihe von Ganzzahlen zurück, anstatt Ihr hydratisiertes FundAllocations Objekt zurückzugeben. Wenn Sie dies dann tun möchten, müssen Sie in Ihrem benutzerdefinierten ModelBinder selbst nachsehen und das Objekt selbst hydratisieren.

Etwas wie:

fund.FundAllocations = 
     repository.Where(f => 
     controllerContext.HttpContext.Request.Form["FundItem.Catalogue.Id"].Contains(f.Id.ToString()); 

Natürlich ist meine LINQ nur zum Beispiel, und Sie können natürlich die Daten abrufen trotzdem, dass Sie wollen. Übrigens, und ich weiß, dass es deine Frage nicht beantwortet, aber nachdem ich viel herumgereicht habe, habe ich entschieden, dass ich für komplexe Objekte am besten ein ViewModel verwende und den Standard-ModelBinder daran binden und dann, wenn es nötig ist, hydratisieren das Modell, das meine Entität darstellt. Es gibt eine Reihe von Problemen, die ich herausgefunden habe und die die beste Wahl getroffen haben. Ich werde Sie jetzt nicht langweilen, aber ich bin froh, wenn Sie es wünschen.

Die neueste Herding Code podcast ist eine gute Diskussion darüber, wie K Scott Allen's Putting the M in MVC blog posts sind.

8

Müssen Sie wirklich einen benutzerdefinierten ModelBinder hier implementieren? Der Standard Bindemittel kann tun, was Sie brauchen (wie es Sammlungen und komplexe Objekte bevölkern können):

sagen Lässt Ihre Controller-Aktion wie folgt aussieht:

public ActionResult SomeAction(Fund fund) 
{ 
    //do some stuff 
    return View(); 
} 

Und Sie html enthält diese:

<input type="text" name="fund.Id" value="1" /> 
<input type="text" name="fund.Name" value="SomeName" /> 

<input type="text" name="fund.FundAllocations.Index" value="0" /> 
<input type="text" name="fund.FundAllocations[0].SomeProperty" value="abc" /> 

<input type="text" name="fund.FundAllocations.Index" value="1" /> 
<input type="text" name="fund.FundAllocations[1].SomeProperty" value="xyz" /> 

Der Standardmodellbinder sollte Ihr Fondsobjekt mit 2 Elementen in der FundAllocations List initialisieren (ich weiß nicht, wie Ihre FundAllocation-Klasse aussieht, also habe ich eine einzelne Eigenschaft "SomeProperty" erstellt). Stellen Sie sicher, dass Sie die "fund.FundAllocations.Index" -Elemente (die die Standardmappe für die eigene Verwendung verwendet) mit einschließen, die mich bekommen haben, als ich versucht habe, dies zum Laufen zu bringen.

+0

JonoW - haben Sie einen Link für eine gute Dokumentation für das Standardmodellbinder, oder haben Sie nur die Quelle betrachtet? –

+0

Will, sorry, habe keinen Link zu irgendeiner offiziellen Dokumentation, ich bin wirklich auf den Rat von Phil Haack auf seinem Blog gegangen, da ich ein ähnliches Problem hatte - http://haacked.com/archive/2008/10 /23/model-binding-to-a-list.aspx. Es kann einen besseren Weg geben, es in 1.0 zu tun, nicht sicher ... – JonoW

+0

Er ist richtig, Sie brauchen kein benutzerdefiniertes Modellbinder. Sie können dies tun, indem Sie das Namensfeld wie oben gezeigt manipulieren. – MedicineMan

Verwandte Themen