如何检索请求的操作方法的属性

问题描述 投票:0回答:2

我正在尝试查看 MVC 3 应用程序中控制器中可能装饰操作方法的任何身份验证属性。我在我自己的 HtmlHelper 扩展方法中执行此操作,这些方法基本上是 ActionLink 的包装器(为您提供运行时可用信息的上下文)。我已经有了一个基本的解决方案,但是重载的方法让它爆炸了。我知道框架在内部将 url 解析为操作方法,但是在查看 System.Web.Mvc.LinkExtensions 的代码后,我仍然没有准确地找到这是如何发生的,所以我有点不知道如何进行来解决这个问题。

这是我迄今为止解决相关方法的代码:

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
}

所以我当前的问题是,当重写方法时,我会得到“发现不明确的匹配”异常。我猜我需要处理 RouteValues 来解析该方法的任何参数,以便我可以明确地识别正确的参数。有人对如何做到这一点有一些指示吗?或者,框架是否已经提供了解决所需确切方法的方法?

非常感谢!

c# asp.net-mvc-3 reflection html-helper
2个回答
2
投票

编辑:更新了方法以包含来自此页面的见解。此最终版本会查看请求的操作方法的

AuthorizationFilters
并检查用户是否有权执行该操作。

所以我深入研究

System.Web.Mvc.ControllerActionInvoker
并找到了我需要的方法和构造函数。
ControllerDescriptor.FindAction()
最终成为关键。下面,我复制了我编写的方法,它将检索所有属性

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();
        
        var controller = (ControllerBase)factory.CreateController(
            htmlHelper.ViewContext.RequestContext, controllerName);
            
        controllerContext = new ControllerContext(
            htmlHelper.ViewContext.RequestContext, controller);
    }
    
    var controllerType = controllerContext.Controller.GetType();
    var controllerDescriptor = new ReflectedControllerDescriptor(controllerType);
    var actionDescriptor = controllerDescriptor.FindAction(
        controllerContext, actionName);
    
    if (actionDescriptor == null)
    {
        return false;
    }
    
    var filters = new FilterInfo(
        FilterProviders.Providers.GetFilters(controllerContext, actionDescriptor)
    );
    
    var authContext = new AuthorizationContext(controllerContext, actionDescriptor);
    foreach (IAuthorizationFilter authFilter in filters.AuthorizationFilters)
    {
        authFilter.OnAuthorization(authContext);
        if (authContext.Result != null)
        {
            return false;
        }
    }
    
    return true;
}

0
投票

添加授权码的正常方法是使用授权过滤器

IAuthorizationFilter.OnAuthorization 提供了一个 AuthorizationContext 对象,该对象具有

ActionDescriptor
属性。

© www.soinside.com 2019 - 2024. All rights reserved.