Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asp.Net core ActionFilter - how to pass varying number of parameters

I'd like to pass varying number of parameters to an ActionFilter. example:

[TypeFilter(typeof(AuthorizeFilter), Arguments = new object[] {PolicyName.CanUpdateModule, PolicyName.CanReadModule })]
public async Task<IActionResult> PutModule([FromRoute] Guid id, [FromBody] Module module)

I defined filter like below and I get the error "InvalidOperationException: A suitable constructor for type 'MyApp.AuthFilters.AuthorizeFilter' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor.". How do I get around this issue?

public class AuthorizeFilter : ActionFilterAttribute
{
    private readonly IAuthorizationService _authService;
    private readonly string[] _policyNames;

    public AuthorizeFilter(IAuthorizationService authService,params string[] policyNames)
    {
        _authService = authService;
        _policyNames = policyNames.Select(f => f.ToString()).ToArray();
    }...
}
like image 759
frosty Avatar asked Jan 03 '23 15:01

frosty


1 Answers

Close but no cigar. You are calling your filter with the wrong parameters. You already are calling it as a TypeFilterAttribute, since you need DI and arguments passed in.

Now you just need to fix your arguments. You want to pass in a string array, but you pass in several strings.

[TypeFilter(typeof(AuthorizeFilter), 
    Arguments = new object[] {
        new string[] { PolicyName.CanUpdateModule,  PolicyName.CanReadModule }
    }
)]
public async Task<IActionResult> PutModule([FromRoute] Guid id, [FromBody] Module module) {
    /*do stuff*/
}

Nontheless, your IAuthorizationService still needs to be registered with your DI container, to be resolved.

Then you need to remove your params keyword from your AuthorizeFilter class:

public class AuthorizeFilter : ActionFilterAttribute
{
    private readonly IAuthorizationService _authService;
    private readonly string[] _policyNames;

    public AuthorizeFilter(IAuthorizationService authService,string[] policyNames)
    {
        _authService = authService;
        _policyNames = policyNames;
    }
    /* ... */
}
like image 108
Marco Avatar answered Jan 05 '23 15:01

Marco