Search code examples
c#asp.net-mvcasp.net-mvc-5audit

What is the clean way to Implement Audit Trail in Asp.net MVC and Web API


I am trying to look for a more clean way to add audit trail function to an exist asp.net MVC and Web Api project which contains hundreds of Controller and ApiController.

The Audit trail log would look like below. Basically I just want to log In what time who did what in this function.

UserID

ActionTime

Controller 

Action

Anything I missed ? If there is . Please correct me. Thanks.

Currently I found there are some ways to make it .

  1. Implement an ActionFilterAttribute and write my own log function in the OnActionExecuting, and then decorate all the actions with this attribute.

  2. Implement a base Controller like BaseController for all the exist controller. And write log in the OnActionExecuting. Then change all the controller to inherit from BaseController. (If it is wrong . Please correct me . Thanks.)

  3. For the ApiController. Implement a DelegatingHandler to make it.

For 1 and 2. I need change to all the exist code to make it. like change base class or decorate with new attribute. Considering in my case, This will be a hard work. Because thousands of class or methods need to be changed . I thinks it is kind of verbose. So I wondered if there is some clean way like 3 for ApiController to make it. Thanks.


Solution

  • Are you using a DI container? If you are or want to use a DI container, that could intercept all requests to the controllers. That way you don't change codes in hundreds of controllers, albeit simple change.

    Here's Castle Windsor DI.

    public class WindsorControllerFactory : DefaultControllerFactory
    {
    private readonly IKernel _kernel;
    
    public WindsorControllerFactory(IKernel kernel)
    {
        _kernel = kernel;
    }
    
    public override void ReleaseController(IController controller)
    {
        _kernel.ReleaseComponent(controller);
    }
    
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
        {
            throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path));
        }
    
        return (IController)_kernel.Resolve(controllerType);
    }
    }
    

    Have a look at the examples on this site if you intended to use it. I am sure there is a way to use it for both Web API and MVC controllers.