8

给定动作名称、控制器名称和 HTTP 动词(GET、POST .. 等),是否可以检查动作是否具有(即被修饰)特定动作过滤器属性?

请注意:动作和控制器不是当前动作和控制器,但可以是应用程序中的任何动作和控制器。

谢谢!

4

4 回答 4

4

我已经回答了我自己的问题,这与此非常相似。

除了动作和控制器名称之外,您还需要http method(即 GET、POST)来获得正确的结果。

这是解决您的问题的一段代码:

var controllerFactory = ControllerBuilder.Current
    .GetControllerFactory();

var controllerContext = @this.ControllerContext;

var otherController = (ControllerBase)controllerFactory
    .CreateController(
        new RequestContext(controllerContext.HttpContext, new RouteData()),
        controllerName);

var controllerDescriptor = new ReflectedControllerDescriptor(
    otherController.GetType());

var controllerContext2 = new ControllerContext(
    new MockHttpContextWrapper(
        controllerContext.HttpContext.ApplicationInstance.Context,
        method),
    new RouteData(),
    otherController);

var actionDescriptor = controllerDescriptor
    .FindAction(controllerContext2, actionName);
于 2012-10-24T08:01:20.923 回答
2

我有一个类似的问题,我需要检查一个动作是否有自定义属性。

public static IEnumerable<MyCustomAttribute> GetAttributes(string controllerName, string actionName)
    {
        var types = Assembly.GetExecutingAssembly().GetTypes();
        var controllers = types.Where(t => (t.Name == controllerName));
        var action = controllers.SelectMany(type => type.GetMethods().Where(a => a.Name == actionName)).FirstOrDefault();
        return action.GetCustomAttributes<MyCustomAttribute>(true);
    }

归功于这个 SO 答案

于 2015-04-24T15:48:02.783 回答
1

如果有人编写单元测试并且controllerFactory不像他Miguel Angelo的回答那样为他工作,这是我迄今为止想出的最好的:

var ctrl = // your controller instance of type T.
var controllerDescriptor = new ReflectedControllerDescriptor(ctrl.GetType());
var actionDescriptor = new ReflectedActionDescriptor(typeof(T).GetMethod(actionName), actionName, controllerDescriptor);

它不会定位控制器本身(它假定控制器),但您通常可以在编写测试时这样做......

于 2019-02-07T11:59:40.323 回答
0

我不太确定你想在哪个地方检查它。如果您在OnActionExecutingOnActionExecuted中执行此操作。ActionExecutedContext具有属性ActionDescriptor。在那里您可以找到IsDefined方法,该方法可以检查是否为此成员定义了指定属性类型的一个或多个实例。检查代码示例如下:

protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
    var hasAutorizeAttr = filterContext.ActionDescriptor
                            .IsDefined(typeof(AuthorizeAttribute), false);
    base.OnActionExecuted(filterContext);
}

编辑:好的,现在我明白你的问题了。看起来没有优雅的解决方案。如果您需要使用AjaxExtensions.BeginForm方法来检查其他操作,我只看到一种方法 - 反射。但在我看来,在这种情况下,您需要重新考虑您的架构。

于 2012-07-18T17:02:39.493 回答