C# 在ASP.NET内核中执行异步操作';s ActionFilterAttribute

C# 在ASP.NET内核中执行异步操作';s ActionFilterAttribute,c#,asp.net-core,action-filter,C#,Asp.net Core,Action Filter,ASP.NET Core的ActionFilterAttribute具有以下功能: public virtual void OnActionExecuting(ActionExecutingContext context); public virtual void OnActionExecuted(ActionExecutedContext context); public virtual Task OnActionExecutionAsync(ActionExecutingContext co

ASP.NET Core的
ActionFilterAttribute
具有以下功能:

public virtual void OnActionExecuting(ActionExecutingContext context);
public virtual void OnActionExecuted(ActionExecutedContext context);
public virtual Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next);
我需要一个异步版本的
OnActionExecuting
,它不存在

但是,我觉得我可以使用
OnActionExecutionAsync
,因为它还有一个参数
ActionExecutingContext

尽管名称不同,但它们在过程中的同一点触发,对吗

另外,我需要如何处理
下一个
参数?完成我的东西后,我是否只需要调用
wait next()


是这样吗?我不确定,因为我找不到这方面的文档。

异步筛选器的工作方式有点不同:首先执行操作之前必须执行的代码,调用
next()
获取实际逻辑,最后添加操作之后要执行的代码

public async Task OnActionExecutionAsync(ActionExecutingContext context, 
                                         ActionExecutionDelegate next)
{

    // logic before action goes here

    await next(); // the actual action

    // logic after the action goes here
}
文件如下:

异步筛选器始终优先于同步筛选器实现

根据报告:

  • 建议实现过滤器的同步或异步版本接口,而不是两者都实现。运行时首先检查过滤器是否实现了异步接口,如果实现了,则调用该接口。如果不是,则调用同步接口的方法。如果异步和同步接口都在一个类中实现,则只调用异步方法
但是,您可以同时拥有这两种功能。例如:

public class TimestampFilter : IActionFilter, IAsyncActionFilter 
{    
    public void OnActionExecuting(ActionExecutingContext context)    
    {         
        context.ActionDescriptor.RouteValues["timestamp"] = DateTime.Now.ToString();    
    }

    public void OnActionExecuted(ActionExecutedContext context)    
    {         
        var ts = DateTime.Parse(context.ActionDescriptor. RouteValues["timestamp"]).AddHours(1).ToString();        
        context.HttpContext.Response.Headers["X-EXPIRY-TIMESTAMP"] = ts;    
    }

     public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)    
    {        
        this.OnActionExecuting(context);        
        var resultContext = await next();
        this.OnActionExecuted(resultContext);    
    }
 }


更好的模式:

    public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        try
        {
              //do your async things here                 
        }
        finally
        {
            await base.OnActionExecutionAsync(context, next); <--- notice this!
        }
    }
公共重写异步任务OnActionExecutionAsync(ActionExecutionContext上下文,ActionExecutionDelegate下一步)
{
尝试
{
//在这里执行异步操作
}
最后
{

wait base.OnActionExecutionAsync(上下文,下一个);实际上在第二个代码中block@grokky基本实现检查参数并调用其他两个方法。如果不重写其他两个方法,则不需要调用它。@grokky您可以在此处检查源代码:对于那些在委托引发异常时进行搜索的方法,请从
var result=wait next()获取结果;
然后检查
结果。异常