动作过滤器:如何调用服务层和异步方法

Posted

技术标签:

【中文标题】动作过滤器:如何调用服务层和异步方法【英文标题】:Action filter : how to call service layer and async method 【发布时间】:2022-01-20 08:22:54 【问题描述】:

我有一个带有许多操作方法的控制器。我的要求是检查数据库中字段的值,如果字段值为“true”,则所有操作方法都可以执行,否则这些操作方法不应该执行。 方法在服务层

public class CustomAttributeFilter : ActionFilterAttribute

    public  override void  OnActionExecuting(ActionExecutingContext filterContext)
    
        var myFlag = await _adminDB.GetFlagSettingsAsync();
        
        // how do i call async method from OnActionExecuting filter
        if (!myFlag)
        
            //Create your result
            filterContext.Result = new EmptyResult();
        
        else
        
            base.OnActionExecuting(filterContext);
        
    


接口实现

public interface IAdminDB
    
        
        Task<MySettings> GetMySettingsAsync();
    

public class AdminDB : IAdminDB
    
public async Task<MySettings> GetMySettingsAsync()
        
            var dbName = _appSettings.AdminDbName;
            var blobName = _appSettings.AdminBlobName;
            return await _dbStorage.GetBlobAsync<MySettings>(blobName, dbName);
         




public class MySettings
          
        public bool MyFlag  get; set; 
    

我收到一条错误消息“找不到合适的方法来覆盖”。如何清除此错误以及如何正确注入服务。以上是我尝试过的,这里对 async 的调用失败了。

【问题讨论】:

【参考方案1】:

我在您的代码中看不到 _adminDB 依赖项来自何处,但我猜这是导致问题的原因。

如果你想使用异步过滤器,你必须实现 IAsyncActionFilter 接口。

您可以从执行上下文的 DI 容器中检索服务并通过以下方式使用异步方法:

 public class CustomAttributeFilter : ActionFilterAttribute
 
     public override async Task OnActionExecutionAsync(
    ActionExecutingContext context, ActionExecutionDelegate next)
     
         var adminDb = filterContext.HttpContext.RequestServices.GetService<AdminDb>();
         var myFlag = await adminDb.GetFlagSettingsAsync();
         
         //..

         await next();
     
 

根据您的需要,您也可以将自定义逻辑放在 next() 调用之后。

请参阅documentation 了解更多信息。

【讨论】:

谢谢,你能告诉我一个可以使用异步操作过滤器的例子吗 我已经修改了答案,所以示例代码覆盖了 OnActionExecutionAsync 我已经修改了我的问题以包括任务接口实现。 if (!myFlag) //创建你的结果 context.Result = new BadRequestObjectResult("Invalid!"); else // base.OnActionExecuting(context);等待下一个(); 这真的很有帮助,并通过参考您的回答添加了我在评论中所做的回答部分 你能推荐我上面的动作过滤器的单元测试用例文档吗?

以上是关于动作过滤器:如何调用服务层和异步方法的主要内容,如果未能解决你的问题,请参考以下文章

在 MVC 5 操作过滤器中进行异步调用

React中redux的异步性问题?

WFP之WFP简介

ASP.NET MVC学习之过滤器篇

将服务注入动作过滤器

如何创建多个异步java过滤器?