Comment récupérer les attributs de la méthode d'Action demandée

j'essaie de regarder tous les attributs d'authentification qui peuvent être des méthodes d'action décoratives dans Mes controllers dans une application MVC 3. Je le fais dans mes propres méthodes d'extension HtmlHelper qui sont essentiellement des wrappers à ActionLink (pour vous donner le contexte des informations que j'ai disponibles à l'exécution). J'ai une solution de base en place, mais les méthodes surchargées ont juste fait exploser. Je sais que le cadre résout à l'interne les urls des méthodes d'action, mais après avoir cherché par le code du système.Web.Mvc.LinkExtensions, Je n'ai toujours pas trouvé exactement comment cela se passe, donc je suis un peu coincé sur la façon de s'attaquer à cette question.

voici le code que j'ai jusqu'à présent pour résoudre la méthode pertinente:

private static bool _IsUserAuthorized(HtmlHelper html,
  string controllerName, string actionName)
{
  controllerName = controllerName ??
    html.ViewContext.RouteData.GetRequiredString("controller");

  var factory = ControllerBuilder.Current.GetControllerFactory();
  var controller = factory.CreateController(
    html.ViewContext.RequestContext, controllerName);

  Type controllerType = controller.GetType();
  var methodInfo = controllerType.GetMethod(actionName,
    BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);

  ... check authentication
}

donc mon problème actuel est que quand une méthode est dépassée, j'obtiens des exceptions "ambigu match found". Je suppose que je dois traiter les valeurs de RouteValues pour résoudre tous les paramètres de la méthode pour que je puisse identifier sans ambiguïté le droit un. Quelqu'un a-t-il des conseils pour faire ça? Alternativement, le cadre déjà fournir un moyen de résolution de la méthode exacte nécessaire?

Merci beaucoup!

7
demandé sur Nate Kennedy 2012-05-01 00:23:56

2 réponses

EDIT: mise à Jour de la méthode pour inclure des idées à partir de cette page. Cette version finale examine les filtres D'autorisation pour la méthode d'action demandée et vérifie si l'utilisateur est autorisé à effectuer l'action.

alors j'ai creusé dans le système.Web.Mvc.ControllerActionInvoker et j'ai trouvé les méthodes et les constructeurs dont j'avais besoin. ControllerDescriptor.FindAction() a fini par être la clé. Ci-dessous, j'ai copié la méthode que j'ai écrite qui sera récupérer tous les les attributs

private static bool _IsUserAuthorized(HtmlHelper htmlHelper,
  string controllerName, string actionName)
{
  ControllerContext controllerContext = null;
  //if controllerName is null or empty, we'll use the 
  // current controller in HtmlHelper.ViewContext.
  if (string.IsNullOrEmpty(controllerName))
  {
    controllerContext = htmlHelper.ViewContext.Controller.ControllerContext;
  }
  else //use the controller factory to get the requested controller
  {
    var factory = ControllerBuilder.Current.GetControllerFactory();
    ControllerBase controller = (ControllerBase)factory.CreateController(
      htmlHelper.ViewContext.RequestContext, controllerName);
    controllerContext = new ControllerContext(
      htmlHelper.ViewContext.RequestContext, controller);
  }

  Type controllerType = controllerContext.Controller.GetType();
  ControllerDescriptor controllerDescriptor = new ReflectedControllerDescriptor(controllerType);
  ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName);
  if (actionDescriptor == null)
    return false;

  FilterInfo filters = new FilterInfo(FilterProviders.Providers.GetFilters(
    controllerContext, actionDescriptor));

  AuthorizationContext authContext = new AuthorizationContext(controllerContext, actionDescriptor);
  foreach (IAuthorizationFilter authFilter in filters.AuthorizationFilters)
  {
    authFilter.OnAuthorization(authContext);
    if (authContext.Result != null)
      return false;
  }
  return true;
}
2
répondu Nate Kennedy 2012-05-03 13:33:05

la façon normale d'ajouter un code d'autorisation est d'utiliser un Filtre D'Autorisation.

IAuthorizationFilter.OnAuthorization offre AuthorizationContext objet qui a un ActionDescriptor propriété.

0
répondu Nicholas Butler 2012-04-30 20:59:37