2016-11-15 70 views
4

我在我的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; 
      } 
     } 
    } 
} 

不過,我有一個控制器的方法(可能在未來更多)不應該在一個事務中運行。獲得控制器操作以「選擇退出」中間件功能的最佳方式是什麼?

在控制器方法上放置像[NoTransaction]這樣的自定義屬性將會很好。但是,我無法確定是否有任何方法可以從我的中間件的Invoke()方法中解析出正確的哪些控制器操作將被調用(這將使我能夠從該方法中提取屬性並確定是否創建一個交易。)什麼是正確的方法來做到這一點?

回答

1

我認爲你要找的是一個自定義過濾器。

您可以創建一個派生自ActionFilterAttribute的新類。 然後,您可以重寫OnActionExecuting和OnActionExecuted方法來添加事務處理。

然後,您可以將過濾器通過屬性添加到您希望運行它們的方法。 [CustomFilter]以防您命名您的類「CustomFilterAttribute」。

如果您需要更多的控制過濾器類的生命週期,您可以使用ActionFilter作爲ServiceFilter。它需要將其註冊爲服務,並且還允許您使用依賴注入。 ServiceFilter屬性會略有不同:

[ServiceFilter(typeof(CustomFilter))] 

這一個很好的參考是: https://damienbod.com/2015/09/15/asp-net-5-action-filters/

+0

這聽起來很有趣,但我不知道我理解的建議 - 這確實讓我有整個系統的交易對於默認情況下的控制器操作,然後使用該屬性選擇退出? –

+0

我建議的解決方案更適合採用選擇加入方式,並在Filter代碼內部進行事務處理。 對於退出,請查看提供的鏈接中的「將過濾器用作全局過濾器」部分。基本上可以將默認篩選器應用於所有控制器。 然後,您可以添加一個布爾值作爲參數來指定是否要創建事務,並手動將該屬性添加到您希望不創建任何事務的任何位置。 – FelschR

+0

ActionFilter的方法在方法的開始和結束處被調用,因此您需要使事務成爲類的成員。確保你調用了transaction.Dispose(); – FelschR

相關問題