2009-08-21 10 views
3

Comme je sais ValueProviderDictionary prend des valeurs pour la liaison de 3 placesComment désactiver la liaison des valeurs de route dans ASP.NET MVC?

  1. de la forme post
  2. De Route valeurs
  3. partir d'une chaîne de requête

Je veux être en mesure de désactiver la deuxième et les troisièmes options. La seule solution que je vois ici est de créer mon propre ValueProvider personnalisé (copier-coller le fichier source ValueProviderDictionary et supprimer ces deux options à partir de là).

Cette solution est-elle correcte? Y a-t-il des alternatives plus élégantes?

(Si la solution avec une coutume ValueProvider est correcte où il doit être initialisé? Dans une méthode d'action du contrôleur ou dans une ModelBinder personnalisée?)

Merci

+0

Question intéressante +1! –

Répondre

2

J'ai créé l'attribut Action et ValueProvider pour résoudre ce problème. Il s'appelle GetValuesAttribute et StrictValueProviderDictionary resp. Vous pouvez définir le Formulaire source, RouteData ou QueryString. Par exemple, si vous voulez que ValueProvider rechercherait des valeurs dans la forme et peut-être QueryString écrivez ce qui suit au-dessus de votre méthode ou contrôleur:

[GetValues(ValueSource.Form | ValueSource.QueryString)] 
[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create(FormCollection formValues) 
{ 
    ... 
    UpdateModel(myModel); //model will be updated from mentioned sources 

Le code source est placé ici: http://codepaste.net/2kpzct. Le seul problème est que cela ne fonctionnera pas si vous voulez obtenir le modèle peuplé en tant que paramètre.

+0

Des trucs soignés. Merci beaucoup. –

3

Remplacer Controller.Initialize() et réglez la propriété ValueProvider dans cette méthode (après avoir appelé base.Initialize()). Pour éviter de réimplémenter l'ensemble du ValueProviderDictionary, vous pouvez simplement le sous-classer. La seule partie intéressante est que vous devrez copier un petit extrait de ValueProviderDictionary.PopulateDictionary(). Dans votre constructeur, appelez le constructeur de base, puis immédiatement this.Clear(), suivi de this.YourCustomPopulateDictionary(). Cela devrait rendre votre code beaucoup plus petit.

+0

Si j'initialise ValueProvider dans la méthode Initialize du contrôleur, comme je l'ai dit, je n'obtiendrai aucun paramètre ActionMethod qui ne provient pas de Form, j'obtiendrai ArgumentException à la place. L'emplacement d'initialisation de ValueProvider doit donc être OnActionExecuting. Mais maintenant j'obtiendrai toujours des valeurs de RouteData si le contrôleur passera le modèle peuplé en tant que paramètre d'action. Donc, je ne vois toujours pas de solution à 100% pour ce _simple_ problème – mipi

+0

Ah, quand vous l'exprimez comme ça, ça change la question. :) La liaison de paramètres n'est en réalité rien de plus qu'un appel glorifié à UpdateModel(), donc ils sont en fait le même chemin de code. Il y a des surcharges de UpdateModel() qui prennent un IDictionary comme paramètre, et vous pouvez y passer votre fournisseur personnalisé. Une meilleure question, cependant, serait pourquoi essayez-vous de lier des fournisseurs de valeur différents pour les paramètres du modèle que pour les appels à UpdateModel()? Qu'y a-t-il dans votre application qui les différencie? Cela pourrait nous conduire dans une direction plus productive. – Levi

+0

Je veux lier de différents ValueProvider, dans mon cas simple fournisseur de valeurs de formulaire, parce que si je laisse la valeur par défaut, il peut conduire à un comportement inattendu. Si je laisse la valeur par défaut, je devrais toujours faire attention à la correspondance occasionnelle avec les valeurs de RouteData. Par exemple, si l'ID des données de route n'est pas fourni, la valeur par défaut est Chaîne vide et lorsque je mets à jour le modèle lors de la création du modèle, je ne veux pas du tout de cette valeur.Et cela pourrait arriver non seulement à la valeur de l'Id, mais à n'importe quel autre. Et je ne veux pas m'en préoccuper à chaque fois que j'ajoute de nouvelles propriétés ou que j'ajoute de nouvelles valeurs à RouteData. – mipi

Questions connexes