'C# - Custom ActionFilter pass in configuration variables
I have a custom action filter that takes in a property but I need the property to come from my appsettings.json file. I pass my configuration into the controller, but when I try to pass in the "_config.GetValue< string >("myString")" the "_config" is red underlined with the message:
An object reference is required for the non-static field, method, or property 'MyController._config'
Action Filter
public class MyActionFilter : ActionFilterAttribute
{
public string Property1 { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
...
}
}
Controller
[ApiController]
[Route("[controller]")]
public class MyController : ControllerBase
{
private readonly IConfiguration _config;
public MyController(IConfiguration config) {
_config = config;
}
[Authorize]
[HttpPost(Constants.ActionName.MyMethod, Name = nameof(MyMethod))]
[MyActionFilter(Property1 = _config.GetValue<string>("myString"))] // Breaks here!
public ActionResult<string> MyMethod()
{
...
}
}
How can I do this? Or at least, how can I avoid hardcoding a value for my action filter properties?
Solution 1:[1]
Your current approach does not work because constructor parameters and properties of attributes are evaluated at compile time.
You could use the service locator pattern in your filter like so:
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var config = filterContext.HttpContext.RequestServices.GetService<IConfiguration>();
string Property1 = config.GetValue<string>("myString");
}
However, this approach is debatable because the service locator pattern is considered an anti-pattern.
Another approach is to use a ServiceFilter. First, create a constructor for the action filter:
public MyActionFilter(string property1)
{
Property1 = property1;
}
Second, change the action filter to a service filter in the controller:
[ServiceFilter(typeof(MyActionFilter))]
public ActionResult<string> MyMethod()
{
...
}
Third, register the action filter:
builder.Services.AddScoped(p => new MyActionFilter(p.GetService<IConfiguration>().GetValue<string>("myString")));
Here is a great blogpost about the topic: Dependency Injection in action filters in ASP.NET Core.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | kmschaal |
