I'm building a NopCommerce plugin and want to register a custom ActionFilter with a FilterProvider on an ActionMethod that has shared ActionName with other methods.
Here are two of the ActionMethods with same ActionName
[HttpPost, ActionName("Edit")]
[FormValueRequired("cancelorder")]
public ActionResult CancelOrder(int id)
{...}
[HttpPost, ActionName("Edit")]
[FormValueRequired("captureorder")]
public ActionResult CaptureOrder(int id)
{...}
In my filter provider I somehow need to separate the CancelOrder method from CaptureOrder:
public class OrderFilterProvider : IFilterProvider
{
private readonly IActionFilter _actionFilter;
public OrderFilterProvider(IActionFilter actionFilter)
{
_actionFilter = actionFilter;
}
public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
if (actionDescriptor.ControllerDescriptor.ControllerType == typeof(OrderController) &&
actionDescriptor.ActionName.Equals("Edit"))
{
return new Filter[]
{
new Filter(_actionFilter, FilterScope.Action, null)
};
}
return new Filter[] { };
}
}
With this code the filter gets registered on both CancelOrder and CaptureOrder, how can I register it only on the CancelOrder method?
My idea was to separate them based on method name or the parameter value in the FormValueRequired attribute but no luck in finding a way of doing that.
FormValueRequired doesnt have any public properties and looks like:
public class FormValueRequiredAttribute : ActionMethodSelectorAttribute {
private readonly string[] _submitButtonNames;
private readonly FormValueRequirement _requirement;
public FormValueRequiredAttribute(params string[] submitButtonNames):
this(FormValueRequirement.Equal, submitButtonNames)
{
}
public FormValueRequiredAttribute(FormValueRequirement requirement, params string[] submitButtonNames)
{
//at least one submit button should be found
this._submitButtonNames = submitButtonNames;
this._requirement = requirement;
}
}
And here is what it looks like in my debugger: http://www.tiikoni.com/tis/view/?id=4843369
Is there no way to get the name of the method?
The only difference I can see between those 2 actions is the presence of some custom FormValueRequired
attribute which unfortunately you haven't shown nor explain what it does, but I guess it is some action selector. Anyway, you could retrieve this attribute:
public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
if (actionDescriptor.ControllerDescriptor.ControllerType == typeof(OrderController) &&
actionDescriptor.ActionName.Equals("Edit"))
{
// Get the FormValueRequiredAttribute that was used to decorate the action
var formValueRequiredAttribute = actionDescriptor
.GetCustomAttributes(typeof(FormValueRequiredAttribute), false)
.Cast<FormValueRequiredAttribute>()
.FirstOrDefault();
// if the action was decorated with this attribute we could read the
// property that was passed to the constructor (hopefully it is exposed
// as a public property)
if (formValueRequiredAttribute != null &&
formValueRequiredAttribute.SomeParameter == "captureorder")
{
// The CaptureOrder action was invoked
return new Filter[]
{
new Filter(_actionFilter, FilterScope.Action, null)
};
}
}
return new Filter[] { };
}