web-dev-qa-db-ja.com

ASP.NET CoreのActionFilterAttributeでの非同期OnActionExecuting

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を使用できると感じています。

名前にかかわらず、プロセスの同じ時点でトリガーされることを修正できますか?

また、next引数で何をする必要がありますか?作業が終わったら、単にawait next()を呼び出す必要がありますか?

それですか?これに関するドキュメントが見つからないので、よくわかりません。

17
grokky

非同期フィルターの動作は少し異なります。最初にアクションの前に実行する必要があるコードを実行し、実際のロジックに対して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
}

ドキュメントはこちらです: https://docs.Microsoft.com/en-us/aspnet/core/mvc/controllers/filters#implementation

37
jeroenh

非同期フィルターは、常に同期フィルターの実装よりも優先されます。

Docs によると:

  • filterインターフェースの同期バージョンまたは非同期バージョンの両方ではなく、実装することをお勧めします。ランタイムは、最初にフィルターが非同期インターフェイスを実装しているかどうかを確認し、実装している場合はそれを呼び出します。そうでない場合は、同期インターフェースのメソッドを呼び出します。非同期インターフェイスと同期インターフェイスの両方が1つのクラスに実装されている場合、asyncメソッドのみが呼び出されます。

ただし、両方を管理することはできます。例えば:

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);    
    }
 }

0
A. Nadjar