2009-06-09 8 views
36

I ont un type:ASP.NET MVC - mélange personnalisé et modèle par défaut de liaison

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

J'ai créé un modèle de liaison personnalisé en raison des exigences sur l'ordre et l'article, mais Range peuvent toujours utiliser la valeur par défaut Modèle Binder.

Existe-t-il un moyen, dans mon classeur de modèle personnalisé, d'appeler le classeur de modèle par défaut pour renvoyer un objet Range? Je pense que je dois simplement configurer ModelBindingContext correctement, mais je ne sais pas comment.


EDIT

En regardant le premier commentaire et la réponse - il semble que héritant du modèle de liaison par défaut pourrait être utile.

Pour ajouter plus de détails pour ma configuration jusqu'à présent, j'ai:

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 
    } 
} 

Cela pourrait être une façon stupide de le faire ... ceci est mon premier modèle de liaison. Juste en soulignant ma mise en œuvre actuelle.


EDIT # 2

Ainsi, les réponses à outrepasser bindProperty fonctionnera si je peux accrocher dans une méthode comme « Je suis tous fait la liaison » et appeler la méthode usine avec les propriétés.

Je suppose que je devrais vraiment regarder l'implémentation de DefaultModelBinder et quitter être stupide.

+1

Je ne suis pas sûr que ce soit la solution la plus élégante, mais pourriez-vous dériver votre classeur de modèle personnalisé à partir de DefaultModelBinder plutôt que d'implémenter IModelBinder? Ensuite, lorsque vous remplacez BindModel, passez la responsabilité à DefaultModelBinder, le cas échéant. Sinon, utilisez une liaison personnalisée. –

+0

Yah, je vois certains modèles de lieurs vont de IModelBinder et DefaultModelBinder. Je suppose que le DefaultModelBinder a quelques méthodes supplémentaires que je suppose qu'il appelle de la méthode BindModel, de sorte que vous pouvez concentrer vos besoins plus? – anonymous

+0

Cela confirme seulement ma décision d'ignorer ModelBinder et le traitement d'entrée de code et la validation manuellement. Maintenant, je l'ai cohérente, transparente et ajustable aux besoins futurs présents et imaginables. – User

Répondre

24

Essayez quelque chose comme ceci:

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

Je suis probablement stupide ici mais comment implémentez-vous la classe CustomModelBinder, sûrement cela doit être instancié quelque part pour que cela fonctionne? Peut-être en tant qu'attribut dans les paramètres ActionResult? –

49

override la bindProperty du DefaultModelBinder:

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 pour le type de propriété inspedcting au lieu du nom. Blâmer les cordes magiques! –

6

Je pense que je l'aurais enregistré deux classeurs de modèles personnalisés différents, l'un pour l'ordre et l'un pour l'article, et laissez le classeur de modèle par défaut gérer la plage et le IssueForm.

+4

Oui, évidemment, il a été un certain temps depuis que j'ai posé cette question. J'ai fini par regarder le code DefaultModelBinder et réaliser la nature récursive de la liaison de modèle. Je ne me suis pas rendu compte avec un type complexe contenant d'autres types complexes que je pourrais juste définir un modèle de liant pour chacun individuellement. J'ai plutôt pensé que le parent complexe devrait connaître les détails de chaque enfant complexe. – anonymous