קורה שנזקקים ללוג קבוע של כל התעבורה מהאתר לצרכי ניתוח, מסתבר שלקבל את גוף ה RESPONSE ולקשר את זה עם ה REQUEST זה לא פשוט, הפתרון הנ"ל מתבסס על התשובה הזו מסטאק: https://stackoverflow.com/a/1792864.
את הקוד הזה שמים בקובץ Global.asax.cs:
שימו לב ש Application_BeginRequest, Application_AcquireRequestState ו Application_EndRequest יכולים כבר להיות קיימים ומלאים בקוד למטרות אחרות,ואז רק להוסיף את השורות מהקוד שלהלן.
//Fires at the beginning of each request
        void Application_BeginRequest(object sender, EventArgs e)
        {   
            //set Filter to this request's response
            HttpResponse response = HttpContext.Current.Response;
            
            OutputFilterStream filter = new OutputFilterStream(response.Filter);
            response.Filter = filter;
            //Save filter in the current Context
            HttpContext.Current.Items["filter"] = filter;
            //Save the request received time in the current Context
            HttpContext.Current.Items["receivedTime"] = DateTime.Now;
            //
        }
        //Fires when request Session state is acquired.
        void Application_AcquireRequestState(object sender, EventArgs e)
        {
            //save SessionId in the current Context (since when in Application_EndRequest the session control is already back to the IIS and the Session info is gone)
            if (HttpContext.Current != null && HttpContext.Current.Session != null)
            {
                HttpContext.Current.Items["SessionID"] = HttpContext.Current.Session.SessionID;
            }
        }
        void Application_EndRequest(object sender, EventArgs e)
        {
            try
            {
                HttpApplication app = sender as HttpApplication;
                string responseBody = ((OutputFilterStream)HttpContext.Current.Items["filter"]).ReadStream();
                HttpContext con = app.Context;
                System.Diagnostics.Debug.WriteLine(string.Join("\r\n", 
                    new string[] { 
                            "SessionID",(HttpContext.Current.Items.Contains("SessionID") ? HttpContext.Current.Items["SessionID"].ToString() : "NoID"),
                            "ResponseTime", DateTime.Now,
                            "ReceiveTime", HttpContext.Current.Items["receivedTime"].ToString(),
                            "RequestURL", con.Request.Url.ToString(),
                            "RequestHeaders", con.Request.Headers.ToString().Replace("&", " "),
                            "RequestBody", GetRequestBody(),
                            "ResponseHeaders", con.Response.Headers.ToString().Replace("&", " "),
                            "ResponseBody", responseBody,
                            "ResponseStatus", Response.StatusCode.ToString()}));                               
            }
            catch (Exception)
            {
                //Ignore Log Failure
            }
        }
          
        //This class saves copy of the response sent to the Client son we can read the copy for logging
        public class OutputFilterStream : Stream
        {
            private readonly Stream InnerStream;
            private readonly MemoryStream CopyStream;
            public OutputFilterStream(Stream inner)
            {
                this.InnerStream = inner;
                this.CopyStream = new MemoryStream();
            }
            public string ReadStream()
            {
                lock (this.InnerStream)
                {
                    if (this.CopyStream.Length <= 0L ||
                        !this.CopyStream.CanRead ||
                        !this.CopyStream.CanSeek)
                    {
                        return String.Empty;
                    }
                    long pos = this.CopyStream.Position;
                    this.CopyStream.Position = 0L;
                    try
                    {
                        return new StreamReader(this.CopyStream).ReadToEnd();
                    }
                    finally
                    {
                        try
                        {
                            this.CopyStream.Position = pos;
                        }
                        catch { }
                    }
                }
            }
            public override bool CanRead
            {
                get { return this.InnerStream.CanRead; }
            }
            public override bool CanSeek
            {
                get { return this.InnerStream.CanSeek; }
            }
            public override bool CanWrite
            {
                get { return this.InnerStream.CanWrite; }
            }
            public override void Flush()
            {
                this.InnerStream.Flush();
            }
            public override long Length
            {
                get { return this.InnerStream.Length; }
            }
            public override long Position
            {
                get { return this.InnerStream.Position; }
                set { this.CopyStream.Position = this.InnerStream.Position = value; }
            }
            public override int Read(byte[] buffer, int offset, int count)
            {
                return this.InnerStream.Read(buffer, offset, count);
            }
            public override long Seek(long offset, SeekOrigin origin)
            {
                this.CopyStream.Seek(offset, origin);
                return this.InnerStream.Seek(offset, origin);
            }
            public override void SetLength(long value)
            {
                this.CopyStream.SetLength(value);
                this.InnerStream.SetLength(value);
            }
            public override void Write(byte[] buffer, int offset, int count)
            {
                this.CopyStream.Write(buffer, offset, count);
                this.InnerStream.Write(buffer, offset, count);
            }
        }
        //This Method returns the Body for the current requst
        public static string GetRequestBody()
        {
            string sReturn = string.Empty;
            // Regular request body
            using (System.IO.StreamReader sr = new System.IO.StreamReader(HttpContext.Current.Request.InputStream))
            {
                sReturn = sr.ReadToEnd();
            }
            // Web service SOAP request body
            if (string.IsNullOrEmpty(sReturn))
            {
                byte[] b = (byte[])typeof(HttpRequest).InvokeMember("EntityBody", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.GetProperty, null, HttpContext.Current.Request, null);
                if (b != null && b.Length > 0)
                {
                    using (System.IO.StreamReader sr = new System.IO.StreamReader(new System.IO.MemoryStream(b), true))
                    {
                        sReturn = sr.ReadToEnd();
                    }
                }
                else
                {
                    sReturn = "";
                }
            }
            //cut the log to reduce size
            //sReturn = sReturn.Substring(0, (sReturn.Length < 200 ? sReturn.Length : 200));
            //encrypt sensitive info 
            //if (sReturn.Contains("&pwd="))
            //{
            //    sReturn = String.Join("&", sReturn.Split('&').Select(p => (p.ToLower().StartsWith("pwd") ? Encryption.Encrypt(p, "PO12345678") : p)).ToArray());
            //}
           
            return sReturn;
        }
פורסם במקור בפורום CODE613 ב22/06/2017 17:50 (+03:00)