Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do none of my ActionFilters run?

I asked a question earlier today about ActionFilters in ASP.Net MVC. It turned out my problem was really that my ActionFilter is not even running. Among other things I read this article, and I can't find anything he does that I don't.

This is my code:

// The ActionFilter itself
public class TestingIfItWorksAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.Controller.TempData["filter"] = "it worked!";
        base.OnActionExecuting(filterContext);
    }
}

// The Controller Action with the filter applied
[TestingIfItWorks]
public ActionResult Test()
{
    var didit = TempData["filter"];
    return View();
}

A breakpoint in the filter method is never hit when I debug, and TempData["filter"] holds a null value when the view is rendered.

Why is this not working?

like image 557
Tomas Aschan Avatar asked Jun 01 '09 12:06

Tomas Aschan


2 Answers

In case it's helpful to anyone using MVC 4/5:

ActionFilters don't run if you get the namespace of your ActionFilterAttribute or IActionFilter wrong: https://stackoverflow.com/a/13710468/188926

Use System.Web.Http.Filters for Web API, System.Web.Mvc for standard MVC actions.

As in the question, the filter attribute will simply be ignored (no error) if you get it wrong, which makes it difficult to diagnose.

like image 130
Dunc Avatar answered Sep 27 '22 16:09

Dunc


Based on your comments to another answer

When testing via unit tests, the filter is not invoked. If you want to invoke the filter then you'll need mimic the ControllerActionInvoker. It's probably better, to test the filter itself in isolation, then use reflection to ensure that the filter is applied to your action with the correct attributes. I prefer this mechanism over testing the filter and action in combination.

Original

Surely you need an override on your method otherwise you aren't actually replacing the method on the base class. I would have expected the compiler to complain that you needed either a new or override on it. If you don't include the override keyword, it will behave as if you used new. Since the framework invokes it as an ActionFilterAttribute, this means that your method will never get called.

Quoting from MSDN:

If the method in the derived class is not preceded by new or override keywords, the compiler will issue a warning and the method will behave as if the new keyword were present.

like image 24
tvanfosson Avatar answered Sep 27 '22 17:09

tvanfosson