是否可以传递服务过滤器参数?

时间:2017-10-17 22:26:39

标签: c# asp.net-mvc asp.net-core-mvc

我知道使用常规过滤器可以传递如下参数:

[Filter(param="value")]
public ActionResult Action()
{
    return View();
}

public class Filter : ActionFilterAttribute
{
    public string param { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // do something with your parameter...
    }       
}

我有服务过滤器:

// MyCustomFilter.cs    
namespace MyNamespace.Filters
{
    public class MyCustomFilter : ActionFilterAttribute
    {
        public string param { get; set; }

        // The services I'm injecting.
        private ILogger _logger;
        private IM3ObjectRepository _repo;

        public MyCustomFilter(ILogger<MyCustomFilter> logger, IM3ObjectRepository repo)
        {
            _logger = logger;
            _repo = repo;
        }

        public override void OnActionExecuting(ActionExecutingContext ctx)
        {
            _logger.LogInformation("Filter is working.");

            // Get stuff from object repository, based on passed-in parameter.
        }
    }
}

// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddSingleton<IM3ObjectRepository, M3ObjectRepository>();

    services.AddScoped<M3UISecurityFilter>();

    ...
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    loggerFactory.AddSerilog();

    ...
}

// Example of filter being used.
[ServiceFilter(typeof(MyCustomFilter))]
public IActionResult Action(...)
{
    ...
}

过滤器注入了一些服务。但每次我使用该服务时,我也会发送一个参数。

我如何实现传递参数?我找不到任何在线描述如何与常规过滤器类似的内容。它甚至可以用于服务过滤器吗?

3 个答案:

答案 0 :(得分:1)

试着扩展它

public class CustomServiceFilterAttribute : ServiceFilterAttribute
{
    public string Param { get; set; }

    public CustomServiceFilterAttribute(Type type)
        : base(type)
    {

    }
}

并使用

[CustomServiceFilterAttribute(typeof(BaseHttpService), Param = "value")]

答案 1 :(得分:1)

我找到了另一种选择:

// MyCustomFilter.cs
public class MyCustomFilter : ActionFilterAttribute
{
    public string param { get; set; }

    public override void OnActionExecuting(ActionExecutingContext ctx)
    {
        ILogger<MyCustomFilter> logger = (ILogger <MyCustomFilter>)ctx.HttpContext.RequestServices.GetService(typeof(ILogger<MyCustomFilter>));
        IM3ObjectRepository repo = (IM3ObjectRepository)ctx.HttpContext.RequestServices.GetService(typeof(IM3ObjectRepository));

        logger.LogInformation("Filter is working.");

        // Get stuff from object repository, based on passed-in parameter.
    }
}

// Example of filter being used.
[MyCustomFilter(param = "value you want")]
public IActionResult Action(...)
{
    ...
}

而不是注入我需要的服务,而是要求他们。

我现在能够设置和访问我需要的参数。

我没有将此标记为答案,因为它没有回答原始问题。但它确实提供了另一种解决方案。

注意:当然不再需要在 Startup.cs 中添加自定义过滤器的服务。当然,仍然需要使用的服务(例如在这种情况下是对象存储库和记录器)。

答案 2 :(得分:1)

TypeFilterAttribute正是为此定义的。

ServiceFilterAttribute 完全相同,不同之处在于,它使您可以传递不一定从IoC容器解析的构造函数参数。

示例:

module.exports = (sequelize,DataTypes) => {
    var userGroup = sequelize.define('user_group', {
        id: {
            type: Sequelize.SMALLINT,
            allowNull: false,
            primaryKey: true,
            field: 'id'
          },
          name: {
            type: Sequelize.STRING(100),
            allowNull: false,
            field: 'name'
          }
    },{schema: 'schema1', underscored: true, tableName: 'user_group', timestamps: false});
        return userGroup;
} 

This article describes this neatly.