In my MVC project, I want to build a filter that records every controller action. All I'm doing is injecting an ILogger object to log the logs into my table storage. This blog post explains how to make an action filter and how to add it to any action, controller, or global location.


Make an Action filter class:

    namespace Filter {  
        using System;  
        using Microsoft.AspNetCore.Mvc.Filters;  
        using Microsoft.AspNetCore.Routing;  
        using Core.Logging;  
        /// <summary>  
        /// This is tog every action activity  
        /// </summary>  
        /// <seealso cref="Microsoft.AspNetCore.Mvc.Filters.ActionFilterAttribute" />  
        [AttributeUsage(AttributeTargets.Class)]  
        public class LogActionFilterAttribute: ActionFilterAttribute {  
            private readonly ILogger logger;  
            /// <summary>  
            /// Initializes a new instance of the <see cref="LogActionFilterAttribute" /> class.  
            /// </summary>  
            /// <param name="logger">The logger.</param>  
            public LogActionFilterAttribute(ILogger logger) {  
                this.logger = logger;  
            }  
            /// <summary>  
            /// Called when [action executing].  
            /// </summary>  
            /// <param name="context">The filter context.</param>  
            public override void OnActionExecuting(ActionExecutingContext context) {  
                this.Log("OnActionExecuting", context.RouteData);  
                base.OnActionExecuting(context);  
            }  
            /// <summary>  
            /// Called when [action executed].  
            /// </summary>  
            /// <param name="context"></param>  
            /// <inheritdoc />  
            public override void OnActionExecuted(ActionExecutedContext context) {  
                this.Log("OnActionExecuted", context.RouteData);  
                base.OnActionExecuted(context);  
            }  
            /// <summary>  
            /// Called when [result executing].  
            /// </summary>  
            /// <param name="context">The filter context.</param>  
            public override void OnResultExecuting(ResultExecutingContext context) {  
                this.Log("OnResultExecuting", context.RouteData);  
                base.OnResultExecuting(context);  
            }  
            /// <summary>  
            /// Called when [result executed].  
            /// </summary>  
            /// <param name="context">The filter context.</param>  
            public override void OnResultExecuted(ResultExecutedContext context) {  
                this.Log("OnResultExecuted", context.RouteData);  
                base.OnResultExecuted(context);  
            }  
            /// <summary>  
            /// Logs the specified method name.  
            /// </summary>  
            /// <param name="methodName">Name of the method.</param>  
            /// <param name="routeData">The route data.</param>  
            private void Log(string methodName, RouteData routeData) {  
                var controllerName = routeData.Values["controller"];  
                var actionName = routeData.Values["action"];  
                string message = $ "MethodName :{methodName} , controller:{controllerName} , action:{actionName}";  
                this.logger.log(message);  
            }  
        }  
    }  

How to make any controller to use this action filter:

Method 1
If you want the functionality to enable for all controllers by default

In starup.cs write the below line:
services.AddMvc(options =>  

options.Filters.Add(typeof(LogActionFilterAttribute));  

});  

Method 2
If you want to use it in Controller specifically:

In starup.cs write the below line:
services.AddScoped<LogActionFilterAttribute>();    

In Action Method or controller use the below attribute:
[ServiceFilter(typeof(ExampleFilterWithDI))]