How to get ActionDescriptor using action and controller names

Given the name of the action, the name of the controller, and the HTTP verb (GET, POST, etc.), is it possible to check whether the action (i.e. decorated) has an action filter attribute?

Please note: the action and controller are not the current action and controller, but can be any actions and controller in the application.

Thanks!

+7
source share
4 answers

I answered my question, it is very similar to this.

You will also need the http method (this is GET, POST) to get the correct result, in addition to the names of actions and controllers.

This is the part of the code that solves your problem:

 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); 
+4
source

I'm not very sure that I understand where you want to check it. If you do this in OnActionExecuting or OnActionExecuted . ActionExecutedContext has an ActionDescriptor property. There you can find the IsDefined method, which gets the opportunity to check whether one or more instances of the specified attribute type are defined for this member. Check out the sample example below:

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

EDIT: Alright, now I'm getting your problem. There seems to be no elegant solution. If you need to play AjaxExtensions.BeginForm with checking for other actions, I see only one way - Reflection. But, in my opinion, you need to reconsider your architecture in this case.

0
source

I had a similar problem when I needed to check if any action had a special attribute.

 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); } 

Confirm this answer SO>

0
source

This is the best I've come up with so far:

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

Source: https://habr.com/ru/post/920798/


All Articles