Max*_*cob 1 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...
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个服务过滤器:
// 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(...)
{
...
}
Run Code Online (Sandbox Code Playgroud)
过滤器中注入了一些服务。但是每次使用该服务时,我也会发送一个参数。
如何实现传递参数?我在网上找不到任何描述方法,类似于常规的过滤器。服务过滤器甚至可能吗?
TypeFilterAttribute正是为此而定义的。
它与ServiceFilterAttribute完全一样,只是它允许您传递不一定从 IoC 容器解析的构造函数参数。
例子:
[TypeFilter(typeof(LogFilter), Arguments = new object[] {"myLogger"})]
[HttpGet("")]
public IEnumerable<Item> Get()
{
return this.repository.GetAll();
}
Run Code Online (Sandbox Code Playgroud)
我找到了另一种选择:
// 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(...)
{
...
}
Run Code Online (Sandbox Code Playgroud)
我没有注入我需要的服务,而是要它们。
现在,我可以设置和访问所需的参数。
我没有将其标记为答案,因为它没有回答原始问题。但这确实提供了替代解决方案。
注意:当然不再需要在Startup.cs中添加的自定义筛选器服务。当然,在那里仍然需要使用的服务(例如,在这种情况下,对象存储库和记录器)。
只是尝试扩展它
public class CustomServiceFilterAttribute : ServiceFilterAttribute
{
public string Param { get; set; }
public CustomServiceFilterAttribute(Type type)
: base(type)
{
}
}
Run Code Online (Sandbox Code Playgroud)
并使用
[CustomServiceFilterAttribute(typeof(BaseHttpService), Param = "value")]
Run Code Online (Sandbox Code Playgroud)