如何从ActionFilterAttribute访问AppSettings

时间:2018-06-28 18:53:14

标签: c# asp.net-core-2.0 asp.net-core-webapi

我需要从ActionFilterAttribute中的appsettings.json文件中获取值。我遵循了此链接(How can I access AppSettings from an ActionFilterAttribute in ASP.NET Core),但它无济于事,因为我需要将参数传递给自定义过滤器,还需要使用来自appsettings.json的参数。例如

// Filter.cs

[AttributeUsage(AttributeTargets.Method)]
public class ThrottleAttribute : ActionFilterAttribute
{
    public string Count { get; set; }

    private static MemoryCache Cache { get; } = new MemoryCache(new MemoryCacheOptions());

    public override void OnActionExecuting(ActionExecutingContext actionExecutingContext)
    {
        //Compare this.Count with GetValueFromAppSettings.json
    }
}

// Controller.cs

[ApiController]
[Route("api/[controller]")]
public class ValuesController : BaseController
{
    // GET api/values
    [HttpGet]
    [Authorize]
    [Throttle(Count = 15)]
    public ActionResult<IEnumerable<string>> Get()
    {
        return new[] { "value1", "value2" };
    }

}

3 个答案:

答案 0 :(得分:2)

appsettings.json应该在DI中注册,因此您可以将IConfiguration传递给ThrottleAttribute构造函数,并通过DI从中获取值,但是您需要创建工厂使其起作用:

public class ThrottleAttributeFactory: ActionFilterAttribute, IFilterFactory
{
    public string Count { get; set; }

    public bool IsReusable => false;

    public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
    {
        var attribute = serviceProvider.GetService<ThrottleAttribute>();

        attribute.Count = Count;

        return attribute;
    }
}

属性:

public class ThrottleAttribute : ActionFilterAttribute
{
    private readonly IConfiguration _config;

    public string Count { get; set; }

    public ThrottleAttribute(IConfiguration config)
    {
        _config = config;
    }
    //rest of code omitted
}

使用您的方法:

{
    var value = _config.GetValue<int>("json:key");
}

并在控制器中将[Throttle(Count = 15)]替换为[ThrottleAttributeFactory(Count = 15)]

也注册属性:services.AddScoped<ThrottleAttribute>();

答案 1 :(得分:1)

在您的情况下,IFilterFactory实现将是最佳选择。

public class ThrottleAttributeFactory : Attribute, IFilterFactory
{
    public string Count { get; set; }

    public bool IsReusable => false;

    public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
    {
        var filter = serviceProvider.GetService<ThrottleAttribute>();

        filter.Count = Count;

        return filter;
    }
}

然后您可以将其注入构造函数

private readonly IConfiguration config;

public ThrottleAttribute(IConfiguration config)
{
    this.config = config;
}

您必须将[Throttle(Count = 15)]更改为[ThrottleAttributeFactory(Count = 15)]

不要忘记在Startup.cs中注册IConfiguration和属性:

public void ConfigureServices(IServiceCollection services)
{
   ...    
   services.AddSingleton<IConfiguration>(Configuration);
   services.AddScoped<ThrottleAttribute>();
}

答案 2 :(得分:0)

您可以向Throttle类添加静态属性,并将配置值存储在其中。然后,在启动类中,您可以设置该值。

[AttributeUsage(AttributeTargets.Method)]
public class ThrottleAttribute : ActionFilterAttribute
{
    public string Count { get; set; }

    public static string ConfigCount { get; set; }

    private static MemoryCache Cache { get; } = new MemoryCache(new MemoryCacheOptions());

    public override void OnActionExecuting(ActionExecutingContext actionExecutingContext)
    {
        //Compare this.Count with GetValueFromAppSettings.json
    }
}

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    ThrottleAttribute.ConfigCount = Configuration.GetValue<int>("key");
}