【问题标题】:Is it possible to pass a Service Filter parameters?是否可以传递服务过滤器参数?
【发布时间】:2017-10-17 22:26:38
【问题描述】:

我知道使用常规过滤器可以像这样传递参数:

[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(...)
{
    ...
}

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

如何实现传入参数?我在网上找不到任何描述如何与常规过滤器类似的方法。甚至可以使用服务过滤器吗?

【问题讨论】:

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


    【解决方案1】:

    TypeFilterAttribute 正是为此而定义的。

    它与 ServiceFilterAttribute 完全相同,只是它允许您传递不一定从 IoC 容器解析的构造函数参数。

    例子:

    [TypeFilter(typeof(LogFilter), Arguments = new object[] {"myLogger"})]  
    [HttpGet("")]
    public IEnumerable<Item> Get()
    {
        return this.repository.GetAll();
    }
    

    This article describes this neatly.

    【讨论】:

      【解决方案2】:

      我找到了替代方案:

      // 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 中添加的自定义过滤器服务当然不再需要。所使用的服务(例如,在这种情况下,对象存储库和记录器)当然仍然需要在那里。

      【讨论】:

        【解决方案3】:

        尝试扩展它

        public class CustomServiceFilterAttribute : ServiceFilterAttribute
        {
            public string Param { get; set; }
        
            public CustomServiceFilterAttribute(Type type)
                : base(type)
            {
        
            }
        }
        

        并使用

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

        【讨论】:

        • 我用更多代码编辑了这个问题。当我尝试您的建议时,编译器抱怨主构造函数(没有给出与'ServiceFilterAttribute.ServiceFilterAttribute(Type)'的所需形式参数'type'相对应的参数))和OnActionExecuting 方法(MyCustomFilter.OnActionExecuting(ActionExecutingContext)':找不到合适的方法来覆盖)。
        猜你喜欢
        • 2019-01-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-11
        相关资源
        最近更新 更多