I have an MVC2 web application that needs to record the number of unique logins by users. Each time a user logs in, there needs to be a record saved to a database. Just the basics like time, date and the like.
Given that the business requirements are to log only cases in one specific ActionResult (i.e. user logon), shou开发者_JS百科ld I simply write some custom code to fire a record through to the database?
Alternatively, given the company does have a track record of later on changing their mind (uncommon as that is with clients), might I be better to create something a little more robust and use that?
Finally, what about using Log4Net instead? Given that the initial requirements only focus on one small part of one application, is that overkill even though it might be more extensible later?
Advice and lively debate appreciated.
Since you are using the SqlMembershipProvider
, the simplest thing to do might be to add an update trigger
to the aspnet_Membership
table. When LastLoginDate
is updated, the trigger can populate a separate tracking table. You can do the same if you want to track failed login attempts using the FailedPasswordAttemptCount
column.
For more detail on how these fields are updated when the user logs in, see the documentation for the SqlMembershipProvider.ValidateUser method:
When a user is successfully validated, the last activity date and last sign-in date values are updated to the current date and time in the database.
If an incorrect password is supplied to the ValidateUser method, the internal counter that tracks invalid password attempts is incremented by one.
With respect to logging in general, you may want to use a logging framework regardless, and I would suggest NLog.
The need you describe appears to be a great fit for an application/domain event.
When a user logs in, an application wide event should be raised to signal that the event (a user logging in) has occurred. The "event" is a message, I always write these as bags of data with no behavior (nothing but fully public properties), and I usually make them contain all the context (data) necessary for the handlers (which often is simply a single record ID).
Separately, write a handler for the event that records the pertinent information in your database. The handler should be a class that has a single responsibility. If more actions need to happen in response to an event, implement them as individual handlers.
Then, somewhere in the application start-up, handlers must be wired to listen to the application/domain events.
So there will be a bit of infrastructure code required to support this pattern, but it should be simple and short code, which can often be greatly assisted by DI/IoC containers. There is also many examples of implementations available if you google domain events.
This pattern of application/domain events is one I've found to be exceptionally powerful. Employing this pattern has drastically improved my code. I find it much easier to extend the behavior of systems without modifying any of the existing code and that behavior is encapsulated by having a clear spot for, in your example, the code that logs a user in and the code that records statistics about application logins.
Lastly, I would not use Log4Net for this. If you implement the event, the handler should be extremely simple and straightforward, but if you attempt to shoe-horn Log4Net in to perform the persistence, well ... it seems you will end up fighting your tool (Log4Net) to at least some degree - and that can be avoided entirely by just not using it.
精彩评论