can*_*stu 6 .net c# asp.net memorycache asp.net-core
AuthenticationRequiredAttribute类
public class AuthenticationRequiredAttribute : ActionFilterAttribute
{
ILoginTokenKeyApi _loginTokenKeyApi;
IMemoryCache _memoryCache;
public AuthenticationRequiredAttribute(IMemoryCache memoryCache)
{
_memoryCache = memoryCache;
_loginTokenKeyApi = new LoginTokenKeyController(new UnitOfWork());
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var memory = _memoryCache.Get(Constants.KEYNAME_FOR_AUTHENTICATED_PAGES);
string requestedPath = filterContext.HttpContext.Request.Path;
string tokenKey = filterContext.HttpContext.Session.GetString("TokenKey")?.ToString();
bool? isLoggedIn = _loginTokenKeyApi.IsLoggedInByTokenKey(tokenKey).Data;
if (isLoggedIn == null ||
!((bool)isLoggedIn) ||
!Constants.AUTHENTICATED_PAGES_FOR_NORMAL_USERS.Contains(requestedPath))
{
filterContext.Result = new JsonResult(new { HttpStatusCode.Unauthorized });
}
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
}
}
Run Code Online (Sandbox Code Playgroud)
HomeController的
public class HomeController : Controller
{
IUserApi _userApi;
ILoginTokenKeyApi _loginTokenKey;
IMemoryCache _memoryCache;
public HomeController(IUserApi userApi, ILoginTokenKeyApi loginTokenKey, IMemoryCache memoryCache)
{
_loginTokenKey = loginTokenKey;
_userApi = userApi;
_memoryCache = memoryCache;
}
[AuthenticationRequired] // There is AN ERROR !!
public IActionResult Example()
{
return View();
}
}
Run Code Online (Sandbox Code Playgroud)
错误:
错误CS7036没有给出的参数对应于'AuthenticationRequiredAttribute.AuthenticationRequiredAttribute(IMemoryCache)'Project.Ground.WebUI所需的形式参数'memoryCache'
我的问题实际上是:我不能在属性类中使用依赖注入.
我想在没有任何参数的情况下使用该属性.有什么解决方案可以解决吗?我使用依赖注入,但它不能用于属性.我该怎么用呢?
pok*_*oke 14
根据文档,您可以在此处选择一些选项:
如果您的过滤器具有您需要从DI访问的依赖项,则有几种支持的方法.您可以使用以下方法之一将过滤器应用于类或操作方法:
如果您只是想让它快速运行,您可以使用前两个选项之一将过滤器应用于控制器或控制器操作.执行此操作时,您的过滤器不需要是属性本身:
[TypeFilter(typeof(ExampleActionFilter))]
public IActionResult Example()
=> View();
Run Code Online (Sandbox Code Playgroud)
然后ExampleActionFilter可以只实现eg IAsyncActionFilter,你可以使用构造函数注入直接依赖于事物:
public class ExampleActionFilter : IAsyncActionFilter
{
private readonly IMemoryCache _memoryCache;
public ExampleActionFilter(IMemoryCache memoryCache)
{
_memoryCache = memoryCache;
}
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{ … }
}
Run Code Online (Sandbox Code Playgroud)
您也可以使用该[ServiceFilter]属性来获得相同的效果,但是您还需要在您ExampleActionFilter的注册表中注册依赖注入容器Startup.
如果您需要更多灵活性,可以实施自己的过滤器工厂.这允许您编写工厂代码以自己创建实际的过滤器实例.上述可能的实现ExampleActionFilter可能如下所示:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class ExampleActionFilterAttribute : Attribute, IFilterFactory
{
public bool IsReusable => false;
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
{
return serviceProvider.GetService<ExampleActionFilter>();
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用该[ExampleActionFilter]属性使MVC框架ExampleActionFilter使用DI容器为您创建一个实例.
请注意,此实现与基本相同ServiceFilterAttribute.只是自己实现它避免了必须ServiceFilterAttribute直接使用它并允许你拥有自己的属性.
最后,还有另一个快速选项,可以让您完全避免构造函数注入.当您的过滤器实际运行时,它使用服务定位器模式动态地解析服务.因此,不是直接注入依赖项并使用它,而是从上下文中显式检索它:
public class ExampleActionFilter : ActionFilterAttribute
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var memoryCache = context.HttpContext.RequestServices.GetService<IMemoryCache>();
// …
}
}
Run Code Online (Sandbox Code Playgroud)
除了在构造上解决问题外,ActionExecutingContext.HttpContext.RequestServices还应在请求时为您提供对请求服务容器的引用。
所以:
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var svc = filterContext.HttpContext.RequestServices;
var memCache = svc.GetService<IMemoryCache>();
//..etc
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4852 次 |
| 最近记录: |