Search code examples
asp.net-mvcloggingasp.net-mvc-3enterprise-library

How can I log both the Request.InputStream and Response.OutputStream traffic in my ASP.NET MVC3 Application for specific Actions?


For a specific set of Actions I am required to log the incoming Requests InputStream as well as the outgoing Response.OutputStream.

I envision using an ActionFilterAttribute for this and overriding the OnActionExecuted and OnResultExecuted methods.

So I'm starting with this idea...

public class ActionLoggerAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);

        HttpRequestBase request = filterContext.HttpContext.Request;
        // TODO: Log the Request.InputStream
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        base.OnResultExecuted(filterContext);

        HttpResponseBase response = filterContext.HttpContext.Response;
        // TODO: Log the Response.OutputStream
    }
}

Ideally I'll just hook this up with the Enterprise Library logging since I'm already using it for Error logging.

  1. Am I accessing the Input and Output streams at the appropriate time?
  2. Can I use the Enterprise Library to easily log Streams?
  3. Is there an entirely different and better solution to my problem?

Thanks!


Solution

  • In order to capture the response you could use a response filter:

    public class CaptureResponse : MemoryStream
    {
        private readonly Stream _stream;
        public CaptureResponse(Stream stream)
        {
            _stream = stream;
        }
    
        public override void Write(byte[] buffer, int offset, int count)
        {
            // TODO: Log the response buffer here 
            // (note that it could be a chunk)
    
            _stream.Write(buffer, offset, count);
        }
    }
    

    then you could have a custom action attribute:

    public class ActionLoggerAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var request = filterContext.HttpContext.Request;
            var response = filterContext.HttpContext.Response;
            response.Filter = new CaptureResponse(response.Filter);
    
            // TODO: Log the Request.InputStream
    
            base.OnActionExecuting(filterContext);
        }
    }