10

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?

Community
  • 1
  • 1
Tomas Aschan
  • 58,548
  • 56
  • 243
  • 402

3 Answers3

10

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.

Community
  • 1
  • 1
Dunc
  • 18,404
  • 6
  • 86
  • 103
5

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.

tvanfosson
  • 524,688
  • 99
  • 697
  • 795
  • Hm... strange that it did not get in there. I didn't get a warning (until I recompiled) but including override did not change the situation: The code still does not run. – Tomas Aschan Jun 01 '09 at 13:54
  • 1
    Did you do a Rebuild Solution? Perhaps a library is out of date. I can't imagine this not working if you're using override. – tvanfosson Jun 01 '09 at 14:00
  • Thanks! I figured it out about the same time by starting a new, clean project, adding just the necessary to test this (a controller, a filter, a view and a test) and I found out the same thing. I'll look around on the net for some info on unit testing ActionFilters separately and get back with a new question if I fail (again). Big thanks! =) – Tomas Aschan Jun 01 '09 at 15:01
0

In addition to what tvanofosson said, your action method isn't actually rendering anything to the view. Does your view have a <%=TempData["Filter"].ToString()%> statement or something similar?

Rafay
  • 30,950
  • 5
  • 68
  • 101
Chris
  • 27,596
  • 25
  • 124
  • 225
  • No, I don't actually have a view. I have a breakpoint in the ActionResult method in the controller, and a breakpoint in the OnActionExecuting method in the filter, and a UnitTest that calls the action. I hit "Debug test" and stop in the controller action, but not in the filter action. In addition, the unit test tries to assert that TempData["filter"] == "it worked!", and fails. – Tomas Aschan Jun 01 '09 at 13:56
  • Aha -- the attribute isn't invoked from the unit test, it's only invoked by the MVC framework when the method is called by the action executor. – tvanfosson Jun 01 '09 at 14:49