web-dev-qa-db-fra.com

Utilisation de l'attribut ModelBinder et de ModelBinders.Add ()

Quelqu'un peut-il me dire les avantages/inconvénients d'utiliser l'attribut [ModelBinder()] plutôt que d'enregistrer des classeurs de modèle via ModelBinders.Add() dans global.asax?

Un avantage auquel je peux penser est qu’il est plus explicite, alors que s’inscrire dans la variable globale ModelBinders n’est pas aussi évident pour une personne inspectant la méthode d’action.

Un compromis auquel je peux penser est que ce n'est pas réutilisable, car vous devriez ajouter cet attribut à toutes les méthodes d'action devant utiliser ce classeur de modèle, alors que vous enregistrez dans la variable globale ModelBinders le rendra disponible pour toutes les méthodes d'action recevant ce modèle.

Est-ce la seule différence?

En d'autres termes, cela serait-il correct?

  • Si vous utilisez le modèle uniquement dans une méthode d'action (peut-être deux, obtenez + post), utilisez [ModelBinder()].
  • Si vous utilisez le modèle dans plusieurs méthodes d'action, enregistrez-le dans la variable globale ModelBinders.
22
Jerad Rose

Le résultat de ces techniques sera le même, c'est donc une question avec laquelle l'équipe se sent plus à l'aise. Vous pouvez donc proposer une convention comme celle que vous avez indiquée.

Personnellement, je préfère ne pas avoir à définir l'attribut sur chaque méthode d'action qui utilise ce modèle. Je choisirais donc l'une des options suivantes:

  • Définissez l'attribut sur la classe de modèle comme suit:

    [ModelBinder(typeof(MyModelBinder))]
    public class MyModel
    {
        ...
    }    
    
  • Enregistrer globalement le classeur

    ModelBinders.Binders.Add(typeof(MyModel), new MyModelBinder())
    

Une autre raison pour laquelle je préfère l'une de ces raisons est que si vous devez activer manuellement le processus de liaison de modèle, vous pouvez également souhaiter utiliser votre classeur de modèle personnalisé:

public ActionResult SomeActionMethod()
{
     MyModel model = ...

     //manually invoke the model binding process considering only query string data
     //The custom model binder will be used only if it was globally registered
     //in the binders dictionary or set in an attribute of the model class
     TryUpdateModel(model, new QueryStringValueProvider())

     ...
}

Vous avez également la possibilité d'implémenter votre propre logique de sélection des classeurs de modèle en implémentant l'interface IModelBinderProvider et en vous enregistrant dans le fichier global.asax comme dans

ModelBinderProviders.BinderProviders.Add(new CustomModelBinderProvider()) 

Une façon d'utiliser l'attribut dans les paramètres de méthode pourrait être de remplacer, pour cette méthode particulière, le classeur de modèle qui serait utilisé autrement. Vous pouvez donc enregistrer globalement un classeur de modèle pour votre classe et le remplacer par une méthode d'action particulière à l'aide de l'attribut.

En fin de compte, il existe plusieurs options pour sélectionner le classeur de modèles. Dans asp MVC 3, cela sera résolu de la manière suivante (en supposant que vous utilisez le ControllerActionInvoker par défaut)

  1. L'attribut sur le paramètre de l'action. Voir la méthode GetParameterValue de la classe ControllerActionInvoker

  2. Le classeur est revenu d'IModelBinderProvider. Voir la méthode GetBinder dans la classe ModelBinderDictionary

  3. Le classeur inscrit globalement dans le dictionnaire ModelBinders.Binders.

  4. Le classeur défini dans l'attribut [ModelBinder()] pour le type de modèle.

  5. Le DefaultModelBinder.

30
Daniel J.G.

Il me semble que l’avantage d’utiliser un attribut plutôt que d’ajouter à la collection de classeurs de modèle dans Global.asax est que vous pouvez indiquer à la méthode (ou classe) le classeur spécifique à utiliser plutôt que de l’associer à un type spécifique. Vous pouvez ensuite créer le modèle en fonction d'un contexte plutôt que d'un type.

0
user3667333