2019年7月8日 星期一

[ASP.Net Core] Action Filter with Parameter(s)


 ASP.NET Core   Action Filter  



Introduction


Action filters can run code before and after an action method is called.
Sometimes we need to pass parameter(s) to the Action filter.
Here are 2 ways to make it happens:
1.  Inherit Attribute class and create Public prop(s) as the parameter(s) (See how to do it on ASP.NET frameworks)
2.  Use TypeFilter


Related articles



Environment


.NET Core 2.2.104



Implement


Inherit Attribute class and create Public prop(s)

Action filter

public class LogParamFilter : Attribute, IActionFilter
    {
        public EnumAction Action { get; set; }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            string msg = $"[OnActionExecuted] Request for {this.Action.ToString()}";
            var logger = (ILogger<LogParamFilter>)context.HttpContext.RequestServices.GetService(typeof(ILogger<LogParamFilter>));
            logger.LogInformation(msg);
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {
            string msg = $"[OnActionExecuting] Request for {this.Action.ToString()}";
            var logger = (ILogger<LogParamFilter>)context.HttpContext.RequestServices.GetService(typeof(ILogger<LogParamFilter>));
            logger.LogInformation(msg);
        }
    }


Usage

[HttpGet("MyAction1")]
[LogParamFilter(Action = EnumAction.Action1)]
public async Task<IActionResult> MyAction1()
 {
     return Ok();
 }



Use TypeFilter

Action filter

public class LogFilter: IActionFilter
    {
        private readonly ILogger<LogFilter> _logger = null;
        private readonly EnumAction _action;

        public LogFilter(EnumAction action, ILogger<LogFilter> logger)
        {
            this._logger = logger;
            this._action = action;
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            string msg = $"[OnActionExecuted] Request for {this._action.ToString()}";
            this._logger.LogInformation(msg);
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {
            string msg = $"[OnActionExecuting] Request for {this._action.ToString()}";
            this._logger.LogInformation(msg);
        }
    }

Notice that the constructor’s parameters include:

-   Incoming parameter(s), such as EnumAction action. Make sure passing the right number of incoming parameters, or give it a default value.

-   Injected service(s), such as ILogger<LogFilter> logger.

As you can see, TypeFilter is more continent to inject the services from DI container by constructor.



Usage

[HttpGet("MyAction2")]
[TypeFilter(typeof(LogFilter), Arguments = new object[] { EnumAction.Action2 })]
 public async Task<IActionResult> MyAction2()
 {
      return Ok();
 }




Result





Source code




Reference





沒有留言:

張貼留言