Important: This article is written to demonstrate how we can change the request parameters passed to an action in action filters.
But if the concern is how to customize binding the request values to action parameters then the better way is to go for custom model binders.
Action Filters
Filters are behaviors that can be added to different stages in the ASP.NET MVC request processing pipeline.
There are four different types of filters: Authorization, Action, Result and Exception.
The Action filters are the ones that are called before and after an action is executed.
One of the interesting thing with the action filters is, we can even change the parameters before passed
to an action and that s what we are going to see in this article.
IActionFilter
All the action filters should implement the IActionFilter interface.
public interface IActionFilter
{
void OnActionExecuting(ActionExecutingContext filterContext);
void OnActionExecuted(ActionExecutedContext filterContext);
}
The IActionFilter contains two methods. The OnActionExecuting method is called before the action is executed and the OnActionExecuted method
is called after the action is executed.
In our example we are going to change the parameters before the action is called so we have to override the OnActionExecuting method.
Example
Let say we have a controller named OrdersController with a single action Index that returns the list of orders.
public ActionResult Index(int[] ids)
{
}
The Index action takes an integer array (ids) as the input parameter. If the user doesn't pass any id then all
the orders will be returned from the action else only the orders of the passed ids will be returned.
The important thing is multiple order ids are passed as comma separated values to the action for ex.
http://localhost:5555/orders/1,2,3.
Without any customization if the user sends the above request then the value of parameter ids will be null because MVC not
converts the comma separated values into an integer array and there comes our custom action filter for rescue.
In the custom action filter we read the comma separated values, convert into an integer array and set it to the parameter.
So here we go!
public class ParameterConverterAttribute : FilterAttribute, IActionFilter
{
private readonly string _parameterName;
public ParameterConverter(string parameterName)
{
_parameterName = parameterName;
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
var valueProviderResult = filterContext.Controller.ValueProvider.GetValue(_parameterName);
if (valueProviderResult != null)
{
var orders = valueProviderResult.AttemptedValue.ToString().Split(',');
filterContext.ActionParameters[_parameterName] = Array.ConvertAll(orders, s => int.Parse(s));
}
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
}
}
The implementation is quite simple! We are reading the parameter's actual value(AttemptedValue) from the ValueProvider and converting it into an integer array. The converted array is assigned to the corresponsing key in the ActionParameters collection. Since we are passing the parameter name in the constructor we can reuse our custom filter in other controller actions as well.
So we are done with the implementation and the only thing pending is applying it over the action. Let's do it.
[ParameterConverter("ids")]
public ActionResult Index(int[] ids)
{
}
That's it! Now the comma separated IDs are available as an integer array in the action.
I'm a software developer from south tip of India. I spent most of the time in learning new technologies. I've a keen interest in client-side technologies especially JavaScript and admire it is the most beautiful language ever seen.
I like sharing my knowledge and written some non-popular articles. I believe in quality and standards but blames myself for lagging them.
I believe in small things and they makes me happy!