2010-07-14 4 views
2

Je comprends qu'un ModelBinder est un bon endroit pour faire le travail sur la demande afin que vous gardiez ce type de code hors du contrôleur. Travailler avec des valeurs de formulaire serait un exemple. Cela semble logique cependant, j'ai hérité d'une application qui utilise un classeur personnalisé et je n'arrive pas à comprendre comment et pourquoi cela fonctionne.Je ne "reçois" pas ModelBinders dans MVC 2

Le liant lui-même existe pour traiter seulement TimeZoneInfo objets qu'ils (fuseaux horaires) sont utilisés dans l'application il est inscrit dans la méthode Application_Start dans le monde comme si:

binders.Add(new System.Collections.Generic.KeyValuePair<Type, IModelBinder>(typeof(TimeZoneInfo), new TimeZoneInfoModelBinder())); 

de liants est de tapez ModelBinderDictionary. Le liant lui-même ressemble alors à ceci:

public class TimeZoneInfoModelBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     if (bindingContext == null) 
     { 
      throw new ArgumentNullException("bindingContext"); 
     } 
     string tzId = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).AttemptedValue; 


     try 
     { 
      return TimeZoneInfo.FindSystemTimeZoneById(tzId); 
     } 
     catch (Exception ex) 
     { 
      bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex); 
     } 
     return null; 
    } 
} 

maintenant de marcher à travers le code, je sais ce classeur est seulement appelé quand je POST données au serveur qui implique un modèle particulier qui a une propriété TimeZoneInfo sur elle. Mes hypothèses sont les suivantes:

  • Le temps d'exécution « sait » sur tous les modèles et n'Invoque le liant personnalisé lorsqu'il trouve une propriété avec le même type que celui qui a été adoptée pour le liant.
  • La raison pour laquelle cela est fait parce que le type TimeZoneInfo est un type complexe et, par conséquent, ne peut pas être converti implicitement à partir d'une chaîne (données POST)

Est-ce une bonne compréhension de ce particulier par exemple ou ai-je oublié quelque chose?

Merci!

Répondre

1

Vous êtes à proximité ...

Le liant modèle prend en compte toutes les données de la données de formulaire de demande, l'URL chaîne de requête et les paramètres de routage. Le classeur tentera de se lier aux arguments de la méthode d'action et à toutes les propriétés publiques du modèle qui ont à la fois un get et un ensemble définis. Ceci est fait en considérant le nom du paramètre et/ou la propriété publique.

Étant donné que toutes les sources d'entrée sont dans un format de valeur de nom, les noms sont appariés. Par exemple, s'il existe un paramètre de routage "id" et que votre méthode d'action a un argument "id" dans sa signature, le classeur liera le paramètre de routage à cet argument de méthode d'action. S'il existe un champ de formulaire de pays et un modèle avec une propriété de pays public, le classeur de modèle tentera de lier le champ de formulaire au modèle. Etc

Le classeur considère le type de la propriété lors de la liaison. Le modèle de classeur par défaut sait comment lier les propriétés scalaires (int, decimal, DateTime, etc.). Il peut également se lier à une liste (format de clé MyList [0]) ou à un type complexe qui expose à son tour les propriétés enfant (par exemple, le format de clé Rectangle.Width).

L'exemple que vous avez publié ajoute la possibilité de lier à un objet TimeZoneInfo. Ce classeur est appelé car le nom d'un paramètre de formulaire, d'un argument de requête ou d'un paramètre de routage correspond au nom d'une propriété publique sur votre modèle qui expose un getter et un accesseur qui renvoie un objet TimeZoneInfo.

Notez que ModelBinder fonctionne de concert avec le dictionnaire ModelState. Il est important que les entrées utilisateur invalides soient conservées même si elles ne peuvent pas être converties en type cible. Dans ce cas, une erreur est ajoutée au dictionnaire ModelState et la valeur brute du paramètre d'entrée est conservée afin de pouvoir être incluse dans un nouveau rendu du formulaire avec des erreurs de validation.

+0

Merci pour l'explication Rob. – dparsons

Questions connexes