2016-12-12 7 views
1

すべての非同期コントローラアクションに対してTransactionScopeを適用したいとします。すべてのアクションでそれを実行するのではなく、すべてのアクションに適用できるように中央の場所で実行したいのです。私は、Web APIを起動クラスで、その後ApiControllerActionInvoker非同期アクションでTransactionScopeのWebAPIでカスタムIHttpActionInvokerを使用

public class ControllerActionTransactionInvoker : ApiControllerActionInvoker 
{ 
    public override Task<HttpResponseMessage> InvokeActionAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken) 
    { 

     using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) 
     { 
      Task<HttpResponseMessage> result; 

      result = base.InvokeActionAsync(actionContext, cancellationToken); 

      scope.Complete(); 

      return result; 
     } 

    } 
} 

から継承IHttpActionInvokerは今、私はコントローラのアクションを呼び出して取得することができ、新しく作成された1

config.Services.Replace(typeof(IHttpActionInvoker), new ControllerActionTransactionInvoker()); 

でデフォルトIHttpActionInvokerを置き換えるカスタムを作成してみました私は手動で一連のDb操作の例外を発生させ、目的のTransactionプロセスは機能しません。したがって、DBで行われる部分的な作業があります。 Azure apiアプリでapiをホストした後で、まったく動作しません。それはコントローラのアクションが見つかりませんでした。

解決方法

答えて

1

お客様のscopeは、レスポンスを待たずに、コントローラアクションの実行が完了する前に完了し、処分されています。これがうまくいくかもしれませんが

public class ControllerActionTransactionInvoker : ApiControllerActionInvoker 
{ 
    public override async Task<HttpResponseMessage> InvokeActionAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken) 
    { 
     using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) 
     { 
      HttpResponseMessage result = await base.InvokeActionAsync(actionContext, cancellationToken); 
      scope.Complete(); 
      return result; 
     } 
    } 
} 

、あなたもウェブAPIスタックまで高いこれを行うことを検討する必要があります - おそらくハンドラに - あなたは、例えば、他の取引活動を逃す可能性があるとして:代わりに、このようにそれを試してみてくださいハンドラ、フィルタなどに依存します。スコープの内外で必要なものに依存します。

+0

こんにちは、これはローカルで動作します。あとでAzureもチェックします。どうもありがとう! –

関連する問題