Ensuring an action filter is only executed once per request
If you have a view that's composed of the result of more than one action, for example by having something like:
@Html.Action("PartialContentForHome", "Home")
in one view, to pull in the content for another, any action filters that have been registered by adding them to the GlobalFiltersCollection, or by being explicitly decorated on each action will be executed meaning that the code that you've got in there will be executed more than once. If you've written a filter attribute to add a Content-Security-Policy header, for example:
public class ContentSecurityPolicyFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpResponseBase response = filterContext.HttpContext.Response;
response.AddHeader("Content-Security-Policy", "default-src *; img-src * data:; ");
base.OnActionExecuting(filterContext);
}
}
This will mean that the header is in the returned request multiple times. One way to prevent this from happening is to check for the presence of the header in the filter, and then only add it if it's not present:
public class ContentSecurityPolicyFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpResponseBase response = filterContext.HttpContext.Response;
var header = response.Headers["Content-Security-Policy"];
if (header == null)
{
response.AddHeader("Content-Security-Policy", "default-src *; img-src * data:; ");
}
base.OnActionExecuting(filterContext);
}
}
This post is based on a Stack Overflow answer I wrote.