【问题标题】:Execute code before/after every controller action在每个控制器操作之前/之后执行代码
【发布时间】:2014-12-05 13:27:03
【问题描述】:

我有一个想要记录事件的 ASP.NET MVC 应用程序。我已经有一个 Log 类,其中包含我需要的所有工具,但我必须实例化并显式关闭它(因为它会打开文件,所以我不能依赖 GC)。我的操作如下所示:

public ActionResult MainMenu()
{
    CreateLog();

    // Do controller stuff
    Log(message);
    // Do more controller stuff

    CloseLog();
    return View(mModel);
}

或者我可以使用using 块,但它的侵入性会小一些,并且会在异常处理方面造成麻烦。我已经阅读了ActionFilters,我可以使用它来创建和关闭我的日志,但是我将无法访问方法内的日志对象。

你有什么建议吗?如何避免重复代码?

【问题讨论】:

标签: c# asp.net asp.net-mvc


【解决方案1】:

如果其他建议不起作用,或者如果您需要做的不仅仅是记录日志,还请注意您可以覆盖 OnActionExecuting 方法(通常在基类中以供重用)。

// Custom controller.
public class CustomController : Controller
{
    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // Do whatever here...
    }
}

// Home controller.
public class HomeController : CustomController
{
    // Action methods here...
}

【讨论】:

    【解决方案2】:

    我建议您将 Logger(可能是 ILogger)对象作为对控制器的依赖项。您可以通过 DI 容器(例如 Unity)控制此记录器对象的生命周期 - 如果需要,您可以将其生命周期定义为请求范围。此解决方案的另一个好处是您的代码将保持可测试性。

    【讨论】:

    • 很好,但是我将如何登录不是控制器成员的方法?
    • 您可以简单地将您的记录器对象传递给任何其他方法,以便他们也可以使用它。或者,如果它更适合您的需求,您可以将您的记录器(或简单地包装您已经存在的记录器实现)作为Ambient Context
    • 我喜欢环境上下文解决方案(虽然我宁愿不传递日志,因为我更希望我的方法对横切关注点了解不多)。但是,线程安全呢?我需要关闭打开的日志文件,所以每次(在请求结束时),我都必须关闭日志。我不能有一个单例(或准单例),否则它会存在于请求中。多个日志会尝试打开同一个文件,但失败(并丢失事件);单个日志可能会关闭文件,而另一个请求的操作仍有要记录的内容。
    • 如果我理解正确,您有一个控制器使用的类(我们称之为“A”)。用例是您想在“A”类和控制器中使用您的记录器实现。然后你可以将你的 Logger 注入到“A”类和你的控制器中。
    • 换句话说:您的应用程序组件(控制器、服务或任何其他包含业务逻辑的类)不应该知道有关日志记录机制的任何信息。他们只需要知道有一个记录器对象可以记录我的事件。不管怎样。如果您想将来将日志存储在数据库中怎么办?然后,您必须更改存在打开-日志-关闭逻辑的每一段代码。所以我会把文件处理放在记录器实现中。
    【解决方案3】:

    您可以使用模块,因为它们都位于管道中,并且可以为请求的核心执行提供预处理和后处理。 BeginRequest / ActionExecuting 和 EndRequest / ResultExecuted。它们都提供了授权钩子。

    http://msdn.microsoft.com/en-us/library/aa719858(v=vs.71).aspx

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-26
      • 2012-02-01
      • 2019-09-14
      • 1970-01-01
      • 2010-12-16
      相关资源
      最近更新 更多