2009-06-09 12 views
36

Ich habe eine Art:ASP.NET MVC - Mischen Benutzerdefinierte und Standardmodell Bindung

public class IssueForm 
{ 
    Order Order {get; set;} 
    Item Item {get; set;} 
    Range Range {get; set;} 
} 

Ich habe ein benutzerdefiniertes Modell Bindemittel aufgrund Anforderungen an die Auftrags- und Artikel, aber Bereich könnte noch das Standard-Modell Binder verwenden.

Gibt es einen Weg aus meiner benutzerdefinierten Modellbinder, den Standardmodellbinder aufzurufen, um ein Range-Objekt zurückzugeben? Ich denke, ich muss nur ModelBindingContext richtig einrichten, aber ich weiß nicht wie.


EDIT

am ersten Kommentar und Antwort suchen - es scheint, aus dem Standardmodell Bindemittel wie vererben nützlich sein könnte.

Um weitere Besonderheiten für mein Setup hinzufügen, so weit ich habe:

public IssueFormModelBinder : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     Order = //code to pull the OrderNumber from the context and create an Order 
     Item = //code to pull the ItemNumber from the context and create an Item 

     IssueForm form = IssueFormFactory.Create(Order, Item); 

     form.Range = // ** I'd like to replace my code with a call to the default binder ** 

     return form 
    } 
} 

dies eine dumme Art und Weise tun könnte ... dieses Bindemittel mein erstes Modell ist. Ich weise nur auf meine aktuelle Implementierung hin.


EDIT # 2

die Antworten also außer Kraft zu setzen bindProperty wird funktionieren, wenn ich in wie ein Haken kann „Ich bin alle verbindlich done“ Methode und die Fabrik-Methode mit den Eigenschaften nennen.

Ich denke, ich sollte wirklich die DefaultModelBinder-Implementierung betrachten und aufhören, dumm zu sein.

+1

Ich bin mir nicht sicher, ob es die eleganteste Lösung ist, aber könnten Sie Ihren benutzerdefinierten Modellordner von DefaultModelBinder ableiten, anstatt IModelBinder zu implementieren? Wenn Sie BindModel dann überschreiben, übergeben Sie die Verantwortung ggf. an den DefaultModelBinder. Andernfalls verwenden Sie benutzerdefinierte Bindung. –

+0

Yah, ich sehe einige Modellbinder gehen von IModelBinder und DefaultModelBinder. Ich nehme an, dass der DefaultModelBinder ein paar zusätzliche Methoden hat, von denen ich anmaße, dass er von der BindModel-Methode aufruft, damit Sie Ihre Bedürfnisse besser fokussieren können? – anonymous

+0

Es bestätigt nur meine Entscheidung, ModelBinder und Code-Eingabe Verarbeitung und Validierung manuell zu ignorieren. Jetzt habe ich es konsistent, transparent und anpassbar für gegenwärtige und vorstellbare zukünftige Bedürfnisse. – User

Antwort

24

so etwas wie dieses Versuchen:

public class CustomModelBinder : DefaultModelBinder { 
    protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) { 
     if(propertyDescriptor.Name == "Order") { 
      ... 
      return; 
     } 

     if(propertyDescriptor.Name == "Item") { 
      ... 
      return; 
     } 

     base.BindProperty(controllerContext, bindingContext, propertyDescriptor); 
    } 

} 
+0

Ich bin hier wahrscheinlich dumm, aber wie implementieren Sie die CustomModelBinder-Klasse, sicherlich muss das irgendwo instanziiert werden, damit dies funktioniert? Vielleicht als Attribut in den ActionResult-Params? –

49

Überschreibung der bindProperty vom Default:

public class CustomModelBinder:DefaultModelBinder 
     { 
      protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor) 
      { 
       if (propertyDescriptor.PropertyType == typeof(Range)) 
       { 
        base.BindProperty(controllerContext, bindingContext, propertyDescriptor); 
       } 
       // bind the other properties here 
      } 
     } 
+20

+1 für die Angabe des Eigenschaftstyps anstelle des Namens. Tadeln Sie magische Saiten! –

6

glaube ich zwei verschiedene Bindemittel benutzerdefinierte Modell registriert wäre, eine für Ordnung und einen für Artikel, und lassen Sie die Standardmodellbinde den Bereich und das IssueForm behandeln.

+4

Ja, offensichtlich ist es eine Weile her, seit ich diese Frage gestellt habe. Am Ende habe ich mir den DefaultModelBinder-Code angesehen und die rekursive Natur der Modellbindung erkannt. Ich erkannte nicht mit einem komplexen Typ, der andere komplexe Typen enthielt, sondern einfach einen Modellbinder für jeden einzeln definieren konnte. Ich dachte stattdessen, dass das komplexe Elternteil die Details jedes komplexen Kindes kennen müsste. – anonymous

Verwandte Themen