Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActionDescriptor from ControllerContext

Given I have access only to ControllerContext and not Action____Contexts what is the optimal way to get the current executing ActionDescriptor?

So far the only method I've found is:

new ReflectedControllerDescriptor(context.Controller.GetType())
    .FindAction(context, context.RouteData.GetRequiredString("action"));

Is this the optimal method?

The fact that class is named ReflectedControllerDescriptor leads me to wonder if there is a heavy cost to this operation as it will be executed on every page request? Related to that is does this class internally cache or should I actually be caching ReflectedControllerDescriptors explicitly?

like image 466
Chris Marisic Avatar asked May 30 '12 20:05

Chris Marisic


People also ask

How to get the actiondescriptor of the actionexecutingcontext?

You could try the ActionDescriptorof the ActionExecutingContextas follows: protected override void OnActionExecuting(ActionExecutingContext filterContext) { string actionName = filterContext.ActionDescriptor.ActionName; string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName .....

How to create a controller in ASP NET Core?

As you can see, the IControllerActivator.Create method is passed a ControllerContext which defines the controller to be created. How the controller is created depends on the particular implementation. Out of the box, ASP.NET Core uses the DefaultControllerActivator, which uses the TypeActivatorCache to create the controller.

How to check if an attribute type is defined in actiondescriptor?

ActionExecutedContext has property ActionDescriptor. There you can find IsDefined method which gets possibility to check whether one or more instances of the specified attribute type are defined for this member. Check code sample bellow: EDIT: OK, now I get your issue.

Why doesn't the defaultcontrolleractivator resolve the controller instance from the DI container?

The DefaultControllerActivator doesn't attempt to resolve the Controller instance from the DI container itself, only the Controller's dependencies. To demonstrate this behaviour, I've created a simple MVC application, consisting of a single service, and a single controller.


Video Answer


1 Answers

Doing some digging into the MVC source that's pretty much the most optimal way without copying all the methods required to do what you're already doing. However, I don't see why you couldn't cache found actions so that subsequent calls are more performant.

Internally ReflectedControllerDescriptor also caches the results though there seems to be a bit of overhead since it checks all attributes each time. It looks to be for stuff like HttpPostAttribute and what not.

My suggestion would be to stick with what you're using rather than cache it yourself. If, for some reason, the way the underlying method works changes you're up to date already and wont' have to worry about changing the way you store cached items.

like image 119
Buildstarted Avatar answered Oct 11 '22 15:10

Buildstarted