asp.netコアアプリケーションにミドルウェアをセットアップして、コントローラーのアクションをトランザクション内で自動的にラップします。コントローラーからミドルウェアに情報を渡す
public async Task Invoke(HttpContext context, MyDataContext dbContext)
{
if (context.Request.Method == "GET")
{
await _next(context);
}
else
{
using (var transaction = await dbContext.Database.BeginTransactionAsync())
{
try
{
await _next(context);
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
throw;
}
}
}
}
しかし、トランザクションでは実行しないでください(将来的にはこれ以上)コントローラメソッドが1つあります。コントローラのアクションをミドルウェア機能の「オプトアウト」にする最良の方法は何でしょうか?
[NoTransaction]のようなカスタム属性をコントローラメソッドに配置するとよいでしょう。しかし、私はミドルウェアのInvoke()メソッドから正確にのコントローラアクションが呼び出される(これにより、そのメソッドから属性を引き出して、作成するかどうかを決定することができます)トランザクション)これを行う正しい方法は何でしょうか?
これは面白い聞こえるが、私は提案を理解していない - これは私がシステム全体のトランザクションを持つことができません既定でコントローラのアクションを行い、属性を使用してオプトアウトしますか? –
私の提案するソリューションは、オプトインアプローチを採用し、フィルタコード内でトランザクション処理を行う方が適しています。 オプトアウトについては、提供されたリンクの「グローバルフィルタとしてのフィルタの使用」を参照してください。基本的にすべてのコントローラにデフォルトフィルタを適用できます。 これで、トランザクションを作成するかどうかを指定し、トランザクションを作成しない場所に属性を手動で追加するかどうかを指定するブール値をパラメータとして追加できます。 – FelschR
ActionFilterのメソッドはメソッドの始めと終わりに呼び出されるので、トランザクションをクラスのメンバにする必要があります。 transaction.Dispose();を呼び出してください。 – FelschR