2012-12-19 16 views
7

Mam taką metodę działania, jak poniżej.DefaultModelBinder i kolekcja dziedziczonych obiektów

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

Mam model z następujących klas, które chciałbym załadować dane z danych ajax JSON.

public class Form 
{ 
    public string title { get; set; } 

    public List<FormElement> Controls { get; set; } 

} 

public class FormElement 
{ 
    public string ControlType { get; set; } 

    public string FieldSize { get; set; } 
} 

public class TextBox : FormElement 
{ 
    public string DefaultValue { get; set; } 
} 

public class Combo : FormElement 
{ 
    public string SelectedValue { get; set; } 
} 

Oto dane JSON.

Program DefaultModelBinder obsługuje strukturę obiektów zagnieżdżonych, ale nie może rozstrzygać różnych podklas.

Jaki byłby najlepszy sposób na załadowanie listy do odpowiednich podklas?

+0

Czy możesz wyjaśnić bardziej szczegółowo, co próbujesz osiągnąć tutaj? Wygląda na to, że próbujesz powiązać cały formularz z modelem podglądu zamiast tylko wartościami, które przenosi. Rozumiem, że generowanie formularzy jest dynamiczne w oparciu o dane JSON, które udostępnia backend, ale mam trudności ze zrozumieniem, dlaczego chciałbyś przekazać backendowi samą strukturę zamiast wartości tylko wtedy, gdy użytkownik wypełni formularz. –

+0

Nie generuję dynamicznie formularza. Akceptuję jsona, który reprezentuje strukturę formularza, który zostanie zapisany później w systemie. – Thurein

Odpowiedz

1

Zajrzałem do kodu implementacji DefaultModelBinder mvc. Podczas wiązania modelu DefaultModelBinder wyszukaj właściwości modelu za pomocą metody GetModelProperties(). Poniżej znajduje się wyglądać jak DefaultModelBinder właściwości:

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

TypeDescriptorHelper.Get korzysta ModelType który jest typem partent (w moim przypadku FormElement), a więc właściwości klasy dziecięcej (TextBox, Combo) nie są pobierane .

Można zastąpić metodę i zmienić zachowanie, aby pobrać określony typ dziecka, jak poniżej.