在MVC中记录事件 - 哪种方法最适合?

时间:2010-11-23 23:49:56

标签: design-patterns asp.net-mvc-2 architecture logging

我有一个MVC2 Web应用程序需要记录用户的唯一登录数。每次用户登录时,都需要将记录保存到数据库中。只是时间,日期等基础知识。

鉴于业务要求只记录一个特定ActionResult中的案例(即用户登录),我是否应该编写一些自定义代码来将记录发送到数据库?

或者,考虑到公司确实有改变主意的记录(与客户不同),我是否可以更好地创建更强大的东西并使用它?

最后,使用Log4Net怎么样?鉴于初始要求只关注一个应用程序的一小部分,即使它可能在以后更具可扩展性,这是否过度?

建议和热烈的辩论赞赏。

2 个答案:

答案 0 :(得分:1)

您描述的需求似乎非常适合应用程序/域事件。

当用户登录时,应引发应用程序范围的事件以表示事件(用户登录)已发生。 “事件”是一条消息,我总是把它们写成没有行为的数据包(除了完全公共属性),我通常会让它们包含处理程序所需的所有上下文(数据)(通常只是一个记录ID)。

另外,为记录数据库中相关信息的事件编写处理程序。处理程序应该是一个具有单一责任的类。如果需要在响应事件时采取更多操作,请将它们作为单独的处理程序实现。

然后,在应用程序启动的某个地方,必须连接处理程序以侦听应用程序/域事件。

因此,需要一些基础设施代码来支持这种模式,但它应该是简单而简短的代码,这通常可以通过DI / IoC容器得到极大的帮助。如果您使用Google域事件,还有许多可用的实施示例。

这种应用程序/域事件模式是我发现异常强大的。使用这种模式大大改善了我的代码。我发现在不修改现有代码的任何的情况下扩展系统行为要容易得多,并且通过在您的示例中记录用户登录的代码和记录有关应用程序登录的统计信息的代码。

最后,我不会使用Log4Net。如果你实现了这个事件,那么处理程序应该非常简单明了,但是如果你试图使用Log4Net来执行持久性,那么......好像你最终会对你的工具(Log4Net)进行战斗至少一些学位 - 只要不使用它就可以完全避免。

答案 1 :(得分:1)

由于您使用的是SqlMembershipProvider,因此最简单的方法是将update trigger添加到aspnet_Membership表中。更新LastLoginDate后,触发器可以填充单独的跟踪表。如果要使用FailedPasswordAttemptCount列跟踪失败的登录尝试,则可以执行相同的操作。

有关用户登录时如何更新这些字段的更多详细信息,请参阅SqlMembershipProvider.ValidateUser方法的文档:

  

成功验证用户后,最后一个活动日期和上次登录日期值将更新为数据库中的当前日期和时间。

     

如果为ValidateUser方法提供了错误的密码,则跟踪无效密码尝试的内部计数器会加1。

关于一般的日志记录,您可能想要使用日志框架,我建议NLog