Here is a real life example, where I also access the method info and params inside the action filter attribute:
Suppose I have a Controller Method with ActionAttribute like this:
public class HomeController : Controller
{
...
[FeatureFlagActionAtrribute("user", new String[] { "Feature1" })]
public IActionResult DoSomethingWithFilterAction(String user)
{...}
}
The http call would be something like this:
/Home/DoSomethingWithFilterAction?user="user1"
Now, I want to test the ActionAttribute FeatureFlagActionAtrribute in such a context.
If you would apply above suggestion to this example, it would look like this (worked for me, at least)
var methodInfoDoSomethingWithFilterAction = typeof(HomeController).GetMethod(nameof(HomeController.DoSomethingWithFilterAction));
var httpContext = new DefaultHttpContext();
var routeData = new RouteData();
FeatureFlagActionAtrribute FeatureFlagActionAtrributeFilter = methodInfoDoSomethingWithFilterAction.GetCustomAttribute<FeatureFlagActionAtrribute>();
ActionDescriptor actionDescriptor = new ControllerActionDescriptor()
{
ActionName = methodInfoDoSomethingWithFilterAction.Name,
ControllerName = typeof(FeatureFlagTest).Name,
DisplayName = methodInfoDoSomethingWithFilterAction.Name,
MethodInfo = methodInfoDoSomethingWithFilterAction,
};
ActionContext actionContext = new ActionContext(httpContext, routeData, actionDescriptor) ;
var homeController = new HomeController();
var attribute = new FeatureFlagActionAtrribute("user", new string[] { "feature1" });
IDictionary<string, object> actionArguments = new Dictionary<string, object>
{
["user"] = "user1"
};
var filterMetadata = new List<IFilterMetadata>() { featureFlagActionAtrributeFilter };
ActionExecutingContext actionExecutedContext = new
ActionExecutingContext(actionContext, filterMetadata, actionArguments, homeController);
attribute.OnActionExecuting(actionExecutedContext);
Then inside the ActionFilterAttribute:
public override void OnActionExecuting(ActionExecutingContext context)
{
ControllerActionDescriptor actionDescriptor = (ControllerActionDescriptor)context.ActionDescriptor;
Debug.Print($"2. @Before Method called {actionDescriptor.ControllerName}Controller.{actionDescriptor.ActionName}");
var controllerName = actionDescriptor.ControllerName;
var actionName = actionDescriptor.ActionName;
IDictionary<object, object> properties = actionDescriptor.Properties;
ParameterInfo[] paramsOfMethod = actionDescriptor.MethodInfo.GetParameters();
var fullName = actionDescriptor.DisplayName;
var paramNameForKeyOfFeature = ParamNameForKeyOfFeature;
var arguments = context.ActionArguments;