How can I log both the Request.InputStream and Res

2019-06-14 05:12发布

问题:

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!

回答1:

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);
    }
}