Wednesday 19 September 2018

Action Filters : Do Not Keep State

One thing to remember : Do not keep state in Action Filters of any kind. There is no exception to this rule.

Point to note is that the action filter instance is created only once and then shared across the HTTP requests.

Let us build an example.

I will create 2 action filters.

public class TestFilter : IActionFilter
    {
        private int counter = 0;

        public void OnActionExecuted(ActionExecutedContext filterContext)
        {
            counter++;
            filterContext.HttpContext.Response.Headers.Add("Counter", counter.ToString());
        }

        public void OnActionExecuting(ActionExecutingContext filterContext)
        {
            
        }
    }

    public class TestFilter2 : ActionFilterAttribute
    {
        private int counter = 0;

        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            counter++;
            filterContext.HttpContext.Response.Headers.Add("Counter1", counter.ToString());
        }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {

        }

    }

Let us apply one of the filter as Global Filter and one filter specifically to an Action.

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new TestFilter());

        }

[HttpGet]
        [TestFilter2]
        public ActionResult DoSomething()
        {
            return new JsonResult() { JsonRequestBehavior = JsonRequestBehavior.AllowGet, Data = "Test" };
        }

Now, if we run the application, check the http headers after a few refresh.



You would notice that the counter keeps increasing with each request.

Learning: Do not write an action filter that keeps state.

No comments:

Post a Comment