2009-10-01 7 views
1

Je dois créer quelque chose de similaire à comment MVC invoque une méthode (action) et utilise également le classeur de modèle pour mapper une NamedValueCollection aux paramètres de cette méthode. Fondamentalement, j'ai une action du contrôleur qui doit appeler dynamiquement une méthode sur une classe, le contrôleur a toutes les informations envoyées dans un formulaire ou une chaîne de requête plus le nom de la méthode à invoquer comme une chaîne. En ce qui me concerne, c'est la même chose que d'invoquer une action. Je passe essentiellement un autre niveau (il y a une bonne raison pour laquelle je ne peux pas avoir ces méthodes sur le contrôleur).Comment MVC appelle une action et mappe Request.Form à ses paramètres

J'ai téléchargé la source ASP.Net MVC 1.0 mais il y a un tas de classes, j'ai du mal à trouver le code qui gère cela.

Je sais comment appeler une méthode dont le nom est contenu dans une chaîne, mais il existe peut-être un meilleur moyen que MVC utilise. J'ai également besoin de savoir comment utiliser les reliures de modèle pour créer des chaînes Request.Form + Query à ces paramètres de méthodes.

Si quelqu'un peut me diriger vers le code de la source MVC qui le fait ou me diriger dans la bonne direction en ce qui concerne l'utilisation manuelle du Model Binder par défaut dans MVC, je vous serais reconnaissant. Faites-moi savoir si je peux le rendre plus clair.

Merci

Répondre

3

C'est compliqué. FindAction est appelée sur ControllerActionInvoker. Cela appelle, finalement, ReflectedControllerDescriptor.FindAction, qui à son tour appelle ActionMethodSelector.FindActionMethod, qui appelle RunSelectionFilters sur le même type. Cette méthode prend une liste de méthodes qui lui sont transmises par le collier, et les itère, en examinant les arguments de chaque méthode et en les comparant avec les valeurs de la requête. Parce que cela doit s'exécuter rapidement lorsqu'une requête arrive, tout est mis en cache, et parce qu'il est conçu pour être extensible, il y a des types abstraits entre les couches que j'ai décrites. Par conséquent, il peut être un peu difficile à suivre au début, et il serait probablement difficile de le réutiliser pour une logique non-contrôleur. Cependant, vous pouvez l'utiliser comme un modèle pour implémenter votre propre système. Je pense que c'est un peu trop compliqué pour une application spécifique à un domaine. Le nombre de points d'extension est probablement approprié pour le framework MVC, mais pour votre propre code, YAGNI.

J'espère que cela vous donne assez pour commencer, cependant.

En ce qui concerne l'utilisation d'un classeur modèle sans la pile Web: Eh bien, vous avez toujours besoin de MVC, mais pas nécessairement un serveur Web. Voici comment nous le faisons dans un test unitaire:

internal static T Bind<T>(string prefix, FormCollection collection, ModelStateDictionary modelState) where T:BaseTimeRecordPresentationModel 
    { 
     var mbc = new ModelBindingContext() 
     { 
      ModelName = prefix, 
      ModelState = modelState, 
      ModelType = typeof(T), 
      ValueProvider = collection.ToValueProvider() 
     }; 
     IModelBinder binder = new TimeRecordModelBinder(); 
     var cc = new ControllerContext(); 

     return binder.BindModel(cc, mbc) as T; 
    } 

    internal static T BindAndAssertValid<T>(string prefix, FormCollection collection) where T:BaseTimeRecordPresentationModel 
    { 
     var msd = new ModelStateDictionary(); 
     var result = Bind<T>(prefix, collection, msd); 
     if (!msd.IsValid) 
     { 
      Assert.Fail(ModelStateValidationSummary(msd)); 
     } 
     return result; 
    } 
+0

Oui. J'ai trouvé FindAction et j'ai commencé à voir que ce ne serait pas facile à mettre en communication. J'ai écrit la partie qui trouve la bonne méthode, facile, mais savez-vous s'il est possible d'utiliser les reliures de modèle manuellement? – Damien

+0

Voir la mise à jour. –

Questions connexes