Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.Net Core filters with arguments and DI

Is there a way to make filter with arguments and DI in ASP.NET Core?

My working TestFilterAttribute with TestFilterFilter and DI without arguments:

public class TestFilterAttribute : TypeFilterAttribute
{
    public TestFilterAttribute() : base(typeof(TestFilterFilter))
    {
    }

    private class TestFilterFilter : IActionFilter
    {
        private readonly MainDbContext _mainDbContext;

        public TestFilterFilter(MainDbContext mainDbContext)
        {
            _mainDbContext = mainDbContext;
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {


        }

        public void OnActionExecuted(ActionExecutedContext context)
        {


        }
    }
}

I want to simply use [TestFilter('MyFirstArgument', 'MySecondArgument')] with arguments, instead of [TestFilter] without arguments.

like image 517
J. Doe Avatar asked Mar 13 '17 13:03

J. Doe


People also ask

How do I create a custom filter in .NET Core?

You can create custom filter attributes by implementing an appropriate filter interface for which you want to create a custom filter and derive the FilterAttribute class to use that class as an attribute. For example, implement IExceptionFilter and the FilterAttribute class to create a custom exception filter.

Can we use filters in ASP.NET Core?

Filters in ASP.NET Core allow code to run before or after specific stages in the request processing pipeline. Built-in filters handle tasks such as: Authorization, preventing access to resources a user isn't authorized for. Response caching, short-circuiting the request pipeline to return a cached response.

What is the order of the filters that get executed if multiple filters are implemented?

Filters get executed in the following order for an action: Globally Defined Filters -> Controller-specific Filters -> Action-specific Filters.

What is ActionExecutingContext?

ActionExecutingContext(ControllerContext, ActionDescriptor, IDictionary<String,Object>) Initializes a new instance of the ActionExecutingContext class by using the specified controller context, action descriptor, and action-method parameters.


1 Answers

There is, if you look at the source. Never tried though, so you got to try it yourself (can't test it at work and internet issues at home).

The documentation names one of it, for untyped parameters:

[TypeFilter(typeof(AddHeaderAttribute),
    Arguments = new object[] { "Author", "Steve Smith (@ardalis)" })]
public IActionResult Hi(string name)
{
    return Content($"Hi {name}");
}

The xmldoc of TypeFilterAttribute says

    /// <summary>
    /// Gets or sets the non-service arguments to pass to the <see cref="ImplementationType"/> constructor.
    /// </summary>
    /// <remarks>
    /// Service arguments are found in the dependency injection container i.e. this filter supports constructor
    /// injection in addition to passing the given <see cref="Arguments"/>.
    /// </remarks>
    public object[] Arguments { get; set; }

Alternatively, you can add properties to your TestFilterAttribute and assign them in the constructor, but this only works if the parameter is mandatory and hence set via constructor

public class TestFilterAttribute : TypeFilterAttribute
{
    public TestFilterAttribute(string firstArg, string secondArg) : base(typeof(TestFilterFilter))
    {
        this.Arguments = new object[] { firstArg, secondArg }
    }

    private class TestFilterFilter : IActionFilter
    {
        private readonly MainDbContext _mainDbContext;
        private readonly string _firstArg;
        private readonly string _secondArg;

        public TestFilterFilter(string firstArg, string secondArg, MainDbContext mainDbContext)
        {
            _mainDbContext = mainDbContext;
            _firstArg= firstArg;
            _secondArg= secondArg;
        }

        public void OnActionExecuting(ActionExecutingContext context) { }

        public void OnActionExecuted(ActionExecutedContext context) { }
    }
}
like image 101
Tseng Avatar answered Oct 17 '22 00:10

Tseng