I've broken this up into three parts:
I’ve decided to add more features to the before filter I’ve build in the previous post. I need a way to specify a few methods I’d like to execute before the controller actions. I can do that now by specifying a number of BeforeFilter attributes but that looks a little silly. What I want is the ability to do something like this:
[BeforeFilter("InitializeCategories","InitializeProvinces")]This should be fairly easy to accomplish. We should probably start with a test. I’ve added a logaction method to the test controller so we can assert it was called. Here is the test:
[Test]
public void should_call_all_specified_controller_methods_given_they_exist()
{
controller.Setup(x => x.initialize());
controller.Setup(x => x.logaction());
var attribute = new BeforeFilterAttribute("initialize", "logaction");
attribute.OnActionExecuting(context);
controller.VerifyAll();
}To make this pass we change our implementation slightly. The method names now become a collection we need to iterate over and invoke the method on the controller if found; if not, we throw and exception as before. I've changed the exception type to an InvalidOperationException.
public BeforeFilterAttribute(string methodName) : this(new[] { methodName })
{
}
public BeforeFilterAttribute(params string[] methods)
{
this.methods = new List<string>(methods);
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var controller = filterContext.Controller;
foreach (var method in methods)
{
...
}
base.OnActionExecuting(filterContext);
}This makes the test pass and now we have a BeforeFilter that’s a little more useful and friendly.
I would like to add one more feature to my BeforeFilter and that is an exception list. In other words, I would like a way to specify controller actions for which to NOT execute the methods. That way I have the ability to apply the BeforeFilter to the controller itself instead if the individual action and still retained fine grained control over the before methods that execute for a given action. I will leave that for a separate post.