2012-12-19 10 views
7

Ich habe eine Aktionsmethode wie folgt.DefaultModelBinder und Sammlung von geerbten Objekten

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create(Form newForm) 
{ 
    ... 
} 

Ich habe ein Modell mit den folgenden Klassen, die Ich mag würde die Daten von den Ajax-JSON-Daten zu laden.

Hier sind die JSON-Daten.

DefaultModelBinder verarbeitet die verschachtelte Objektstruktur, kann jedoch die verschiedenen Unterklassen nicht auflösen.

Was wäre der beste Weg, List mit den entsprechenden Unterklassen zu laden?

+0

Können Sie genauer erklären, was Sie hier erreichen möchten? Es scheint, wie Sie versuchen, die ganze Form in das Ansichtsmodell, anstatt nur die Werte zu binden, es trägt. Ich kann den Punkt sieht die Formulare dynamisch basierend auf einigen JSON-Daten bei der Erzeugung des Backend liefert aber ich kämpfen, um zu verstehen, warum Sie nur das Backend wieder die Struktur selbst anstelle der Werte zur Verfügung stellen wollen, wenn ein Benutzer in Form füllt. –

+0

Ich erzeuge nicht die Form dynamisch. Ich bin der Annahme der json, die die Struktur der Form darstellen, die später in dem System gespeichert werden. – Thurein

Antwort

1

Ich habe in den Code der mvc DefaultModelBinder-Implementierung geschaut. Wenn Sie ein Modell DefaultModelBinder binden, suchen Sie die Eigenschaften des Modells mit GetModelProperties(). Hier finden Sie, wie Default die Eigenschaften sehen:

protected virtual ICustomTypeDescriptor GetTypeDescriptor(ControllerContext controllerContext, ModelBindingContext bindingContext) { 
      return TypeDescriptorHelper.Get(bindingContext.ModelType); 
     } 

TypeDescriptorHelper.Get ist Modeltype verwendet, die der partent Typ ist (in meinem Fall FormElement), so die Eigenschaften der untergeordneten Klasse (TextBox, Combo) nicht abgerufen .

können Sie die Methode außer Kraft setzen und das Verhalten ändern, das spezifische Kind wie unten geben abzurufen.

protected override System.ComponentModel.PropertyDescriptorCollection GetModelProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) 
{ 
    Type realType = bindingContext.Model.GetType(); 
    return new AssociatedMetadataTypeTypeDescriptionProvider(realType).GetTypeDescriptor(realType).GetProperties(); 
} 


protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) 
     { 
      ValueProviderResult result; 
      result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".ControlType"); 

      if (result == null) 
       return null; 

      if (result.AttemptedValue.Equals("TextBox")) 
       return base.CreateModel(controllerContext, 
         bindingContext, 
         typeof(TextBox)); 
      else if (result.AttemptedValue.Equals("Combo")) 
       return base.CreateModel(controllerContext, 
         bindingContext, 
         typeof(Combo)); 
      return null; 
     } 
Verwandte Themen