ASP.NET MVC - Adding Action Filters Programmatically

I did some research into action filters and wondered if there was a way to add them programmatically to controllers.

To give some context, I would like to add a registration filter if a log is configured in web.config, otherwise I do not want the filter to exist in the execution chain of each action method.

I appreciate that I can put a check in the filter code itself to see if logging is turned on, but they don’t want to.

Thank you very much!

+4
source share
5 answers

A better solution would be to use a null object template.

Your filter will be registered in the normal mode (its task is to register, and not decide how to register or what to do with the journal, it is necessary), but by default the actual registrar will be an implementation that does nothing. If configured, the log instance will be a registry that is logged as configured.

A simple factory can decide which registrar implementation to deliver to the filter or any IOC container can be configured to handle it.

+1
source
[LogRequest] [PermissionRequired(Permits.View_users, Permits.Edit_users)] public ActionResult Edit(int id, .....) { ... } public class PermissionRequired : ActionFilterAttribute, IActionFilter { private readonly PermissionsList permits; public PermissionRequired(params Permits[] perm) { permits = new PermissionsList(perm); } #region IActionFilter Members void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext) { ... IEnumerable<int> intersection = (from up in User.CurrentUser.UserPermission select up.PermissionID).ToList().Intersect(permits.Cast<int>()); if (intersection.Count() != permits.Count) { filterContext.Result = null; HttpContext.Current.Response.Redirect("/Error/PermissionsRequired.htm"); } } #endregion } 
+1
source

I never added attributes to methods programmatically, as it looks like an inefficient nightmare, for which I always found a preferred alternative.

You need to check somewhere, and although I agree that the attribute code may not be the best for him, this is not particularly bad. If you really do not want to do this, you can ignore the logging code so that it includes only the types of records that were included, and then you how much architecture you want to place around.

0
source

You can start creating your own implementation of ActionInvoker, which is a class that handles calls to filters and action methods. Having said that I do not think this is a good solution. This violates the separation of concerns. It is better that your filter of actions in the log determines whether registration should occur or not.

0
source

I was looking through the new Oxite code (the latest version has undergone major refactoring due to mass critics) and they are doing something interesting. They create their own ActionFilterRepository to store various filters (IActionFilters, IAuthorizationFilters, etc.). In the custom ControllerActionInvoker, the GetFilters method is overridden and adds filters from the repository to the current collection. Thus, they have a set of global filters applied to each action and controller.

Here you can see the custom call code: OxiteControllerActionInvoker.cs

And a filter example here: LocalizationActionFilter.cs

Hope this helps.

0
source

All Articles