2016-11-15 34 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

相关问题