【问题标题】:log request json data记录请求json数据
【发布时间】:2011-07-13 11:10:37
【问题描述】:

假设我正在做来自客户端的网络服务请求。请求由带有 json 参数的 POST 发出。
在服务器中,Context.Request.RawUrl 保存请求 url。但是什么保存了请求 json 数据?

我需要这个属性来记录请求。

这里是http模块的代码:

  public class RequestResponseLoggerModule : IHttpModule
    {
        //private static Logger logger = LogManager.GetCurrentClassLogger();

        #region ResponseCaptureStream

        private class ResponseCaptureStream : Stream
        {
            private readonly Stream _streamToCapture;
            private readonly Encoding _responseEncoding;

            public string StreamContent { get; private set; }            

            public ResponseCaptureStream(Stream streamToCapture, Encoding responseEncoding)
            {
                _responseEncoding = responseEncoding;
                _streamToCapture = streamToCapture;
            }

            public override bool CanRead { get { return _streamToCapture.CanRead; } }
            public override bool CanSeek { get { return _streamToCapture.CanSeek; } }
            public override bool CanWrite { get { return _streamToCapture.CanWrite; } }
            public override long Length { get { return _streamToCapture.Length; } }
            public override long Position
            {
                get { return _streamToCapture.Position; }
                set { _streamToCapture.Position = value; }
            }


            public override void Flush()
            {
                _streamToCapture.Flush();
            }           

            public override int Read(byte[] buffer, int offset, int count)
            {
                return _streamToCapture.Read(buffer, offset, count);
            }

            public override long Seek(long offset, SeekOrigin origin)
            {
                return _streamToCapture.Seek(offset, origin);
            }

            public override void SetLength(long value)
            {
                _streamToCapture.SetLength(value);
            }

            public override void Write(byte[] buffer, int offset, int count)
            {
                StreamContent += _responseEncoding.GetString(buffer);
                _streamToCapture.Write(buffer, offset, count);
            }

            public override void Close()
            {
                _streamToCapture.Close();
                base.Close();
            }
        }

        #endregion

        #region IHttpModule Members

        private HttpApplication _context;
        public void Dispose()
        {

        }

        private static string Extensions_Key = "RequestResponseLoggerModule.Extensions";
        private static string Files_Key = "RequestResponseLoggerModule.Files";
        private static string Request_Key = "RequestResponseLoggerModule.Request";
        private static string Response_Key = "RequestResponseLoggerModule.Response";

        private IEnumerable<string> _Extenstions = new string[] { };
        private IEnumerable<string> _Files = new string[] { };
        private bool _LogAlwaysRequest = false;
        private bool _LogAlwaysResponse = false;

        public void Init(HttpApplication context)
        {
            _Extenstions = ConfigurationManager.AppSettings[Extensions_Key].ToLower().Split(',').
                Select(x => x.Trim()).ToArray();
            _Files = ConfigurationManager.AppSettings[Files_Key].ToLower().Split(',').
                Select(x => x.Trim()).ToArray();
            _LogAlwaysRequest = ConfigurationManager.AppSettings[Request_Key] == "ALWAYS";
            _LogAlwaysResponse = ConfigurationManager.AppSettings[Response_Key] == "ALWAYS";

            _context = context;

            context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
            context.PreSendRequestContent += new EventHandler(context_PreSendRequestContent);
        }

        void context_PreRequestHandlerExecute(object sender, EventArgs e)
        {
            _context.Response.Filter = new ResponseCaptureStream(_context.Response.Filter, _context.Response.ContentEncoding);
        }

        void context_PreSendRequestContent(object sender, EventArgs e)
        {
            bool isMatch = false;
            if (_Extenstions.Count() > 0)
            {
                string ext = VirtualPathUtility.GetExtension(_context.Request.FilePath).
                    Substring(1).ToLower();
                if (_Extenstions.Contains(ext))
                {
                    isMatch = true;
                }
            }
            if (_Files.Count() > 0)
            {
                string fileName = VirtualPathUtility.GetFileName(_context.Request.FilePath).                   ToLower();
                if (_Files.Contains(fileName))
                {
                    isMatch = true;
                }
            }

            if (_LogAlwaysRequest || isMatch)
            {
                string requestText = _context.Request.RawUrl; <------------------

                //log the responseText, but this reurns just the url while I need the data of the webservice call
            }
            if (_LogAlwaysResponse || isMatch)
            {
                ResponseCaptureStream filter = _context.Response.Filter as ResponseCaptureStream;
                if (filter != null)
                {
                    string responseText = filter.StreamContent;
                    //log the responseText
                }
            }        
        }

        #endregion
    }

【问题讨论】:

  • 您能否在问题中提供更多信息,以便我们准确了解您要做什么?
  • 我们能否准确了解您的发送方式,以便我们清楚您发送的内容?

标签: c# .net asp.net web-services


【解决方案1】:

如果您在有效负载中使用 json 进行了 POST,那么您需要读取请求正文。您可以通过使用 Request.InputStream 来做到这一点,例如:

        string json;
        using (var reader = new StreamReader(Request.InputStream))
        {
            json = reader.ReadToEnd();
        }

不过,您需要小心 - 因为消耗身体可能意味着您的实际代码无法读取它。这会很糟糕。

【讨论】:

  • 所以没有办法记录请求数据??
  • @Naor 这很棘手 - 您可以尝试欺骗传入的请求流,特别是如果您的代码使用 MVC 抽象等,但这可能很棘手。恐怕我不能给你一个“这肯定会奏效”的答案。
  • @Marc Gravell:这个怎么样:stackoverflow.com/questions/1038466/…
  • 我添加了一个有效的答案。能说说你的看法吗?
【解决方案2】:
public class RequestResponseLoggerModule : IHttpModule
{
    //private static Logger logger = LogManager.GetCurrentClassLogger();

    #region CaptureStream

    private class CaptureStream : Stream
    {
        private readonly Stream _streamToCapture;
        private readonly Encoding _encoding;

        public string StreamContent { get; private set; }

        public CaptureStream(Stream streamToCapture, Encoding encoding)
        {
            _encoding = encoding;
            _streamToCapture = streamToCapture;
        }

        public override bool CanRead { get { return _streamToCapture.CanRead; } }
        public override bool CanSeek { get { return _streamToCapture.CanSeek; } }
        public override bool CanWrite { get { return _streamToCapture.CanWrite; } }
        public override long Length { get { return _streamToCapture.Length; } }
        public override long Position
        {
            get { return _streamToCapture.Position; }
            set { _streamToCapture.Position = value; }
        }


        public override void Flush()
        {
            _streamToCapture.Flush();
        }           

        public override int Read(byte[] buffer, int offset, int count)
        {
            return _streamToCapture.Read(buffer, offset, count);
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            return _streamToCapture.Seek(offset, origin);
        }

        public override void SetLength(long value)
        {
            _streamToCapture.SetLength(value);
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            StreamContent += _encoding.GetString(buffer);
            _streamToCapture.Write(buffer, offset, count);
        }

        public override void Close()
        {
            _streamToCapture.Close();
            base.Close();
        }
    }

    #endregion

    #region IHttpModule Members

    private HttpApplication _context;
    public void Dispose()
    {

    }

    private static string Extensions_Key = "RequestResponseLoggerModule.Extensions";
    private static string Files_Key = "RequestResponseLoggerModule.Files";
    private static string Request_Key = "RequestResponseLoggerModule.Request";
    private static string Response_Key = "RequestResponseLoggerModule.Response";

    private IEnumerable<string> _Extenstions = new string[] { };
    private IEnumerable<string> _Files = new string[] { };
    private bool _LogAlwaysRequest = false;
    private bool _LogAlwaysResponse = false;
    private bool _IsMatch = false;

    public void Init(HttpApplication context)
    {
        _Extenstions = ConfigurationManager.AppSettings[Extensions_Key].ToLower().Split(',').
            Select(x => x.Trim()).ToArray();
        _Files = ConfigurationManager.AppSettings[Files_Key].ToLower().Split(',').
            Select(x => x.Trim()).ToArray();
        _LogAlwaysRequest = ConfigurationManager.AppSettings[Request_Key] == "ALWAYS";
        _LogAlwaysResponse = ConfigurationManager.AppSettings[Response_Key] == "ALWAYS";

        _context = context;

        context.BeginRequest += new EventHandler(context_BeginRequest);
        context.PreSendRequestContent += new EventHandler(context_PreSendRequestContent);
    }

    void context_PreRequestHandlerExecute(object sender, EventArgs e)
    {
        _context.Response.Filter = new CaptureStream(_context.Response.Filter, _context.Response.ContentEncoding);
    }

    void context_BeginRequest(object sender, EventArgs e)
    {
        if (_Extenstions.Count() > 0)
        {
            string ext = VirtualPathUtility.GetExtension(_context.Request.FilePath).
                Substring(1).ToLower();
            if (_Extenstions.Contains(ext))
            {
                _IsMatch = true;
            }
        }
        if (_Files.Count() > 0)
        {
            string fileName = VirtualPathUtility.GetFileName(_context.Request.FilePath).ToLower();
            if (_Files.Contains(fileName))
            {
                _IsMatch = true;
            }
        }

        if (_LogAlwaysRequest || _IsMatch)
        {
            StreamReader reader = new StreamReader(_context.Request.InputStream);
            string requestText = reader.ReadToEnd();
            _context.Request.InputStream.Position = 0;
            //LOG requestText
        }
    }

    void context_PreSendRequestContent(object sender, EventArgs e)
    {
        if (_LogAlwaysResponse || _IsMatch)
        {
            CaptureStream filter = _context.Response.Filter as CaptureStream;
            if (filter != null)
            {
                string responseText = filter.StreamContent;
                //LOG responseText
            }
        }
    }

    #endregion
}

【讨论】:

  • 我们遇到了问题。字符串 responseText = filter.StreamContent;正在成为二进制格式。我们正在尝试在将 json 数据发送到客户端之前对其进行过滤。我们做得对吗?你能给我建议吗?我们正在启用 ARR 扩展的 IIS 中对此进行检查。
猜你喜欢
  • 2022-10-24
  • 2015-10-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多