การบันทึกคำขอ / การตอบกลับ HTTP ดิบใน ASP.NET MVC & IIS7


141

ฉันกำลังเขียนบริการบนเว็บ (โดยใช้ ASP.NET MVC) และเพื่อวัตถุประสงค์ในการสนับสนุนเราสามารถบันทึกคำขอและการตอบสนองให้ใกล้เคียงที่สุดกับรูปแบบ raw, on-the-wire (เช่นรวมถึง HTTP วิธีการเส้นทางส่วนหัวทั้งหมดและร่างกาย) ลงในฐานข้อมูล

สิ่งที่ฉันไม่แน่ใจก็คือทำอย่างไรถึงจะได้รับข้อมูลนี้อย่างน้อย 'ยุ่งเหยิง' ฉันสามารถประกอบสิ่งที่ฉันเชื่อว่าคำขอดูเหมือนโดยตรวจสอบคุณสมบัติทั้งหมดของHttpRequestวัตถุและสร้างสตริงจากพวกเขา (และในทำนองเดียวกันสำหรับการตอบสนอง) แต่ฉันต้องการรับข้อมูลคำขอ / การตอบสนองที่แท้จริง ส่งไปที่ลวด

ฉันยินดีที่จะใช้กลไกการสกัดกั้นใด ๆ เช่นตัวกรองโมดูลและอื่น ๆ และโซลูชันสามารถเฉพาะกับ IIS7 อย่างไรก็ตามฉันต้องการเก็บไว้ในรหัสที่ได้รับการจัดการเท่านั้น

คำแนะนำใด ๆ

แก้ไข:ฉันทราบว่าHttpRequestมีSaveAsวิธีการที่สามารถบันทึกการร้องขอไปยังดิสก์ได้ แต่สิ่งนี้จะสร้างการร้องขอจากสถานะภายในอีกครั้งโดยใช้วิธีการโหลดตัวช่วยภายในที่ไม่สามารถเข้าถึงได้แบบสาธารณะ กระแสฉันไม่รู้) ดังนั้นมันจึงดูเหมือนว่าฉันจะต้องทำให้ดีที่สุดเพื่อสร้างข้อความคำขอ / ตอบกลับจากวัตถุ ... คร่ำครวญ

แก้ไข 2:โปรดทราบว่าฉันได้กล่าวคำขอทั้งหมดรวมถึงวิธีการเส้นทางส่วนหัว ฯลฯ การตอบสนองปัจจุบันดูเฉพาะกระแสร่างกายซึ่งไม่รวมข้อมูลนี้

แก้ไข 3:ไม่มีใครอ่านคำถามแถวนี้หรือไม่? ห้าคำตอบจนถึงตอนนี้และยังไม่มีใครแม้แต่จะบอกวิธีที่จะได้รับคำขอแบบออนไลน์ทั้งหมด ใช่ฉันรู้ว่าฉันสามารถจับกระแสข้อมูลขาออกและส่วนหัวและ URL และเนื้อหาทั้งหมดจากวัตถุคำขอได้ ฉันพูดไปแล้วว่าในคำถามให้ดู:

ฉันสามารถประกอบสิ่งที่ฉันเชื่อว่าคำขอดูเหมือนโดยตรวจสอบคุณสมบัติทั้งหมดของวัตถุ HttpRequest และสร้างสตริงจากพวกเขา (และคล้ายกันสำหรับการตอบสนอง) แต่ฉันอยากได้รับข้อมูลคำขอ / การตอบสนองที่แท้จริง ที่ถูกส่งไปที่ลวด

หากคุณทราบข้อมูลดิบที่สมบูรณ์ (รวมถึงส่วนหัว, url, วิธี http ฯลฯ ) ก็ไม่สามารถเรียกคืนได้ซึ่งจะเป็นประโยชน์ในการรู้ ในทำนองเดียวกันถ้าคุณรู้วิธีรับทั้งหมดในรูปแบบ raw (ใช่ฉันยังคงหมายถึงส่วนหัว, url, วิธี http ฯลฯ ) โดยไม่ต้องสร้างมันขึ้นมาใหม่ซึ่งเป็นสิ่งที่ฉันถามแล้วมันจะมีประโยชน์มาก แต่การบอกฉันว่าฉันสามารถสร้างขึ้นใหม่ได้จากHttpRequest/ HttpResponseวัตถุไม่มีประโยชน์ ฉันรู้แล้ว. ฉันพูดไปแล้ว


โปรดทราบ: ก่อนที่จะมีใครบอกว่านี่เป็นความคิดที่ไม่ดีหรือจะจำกัดความสามารถในการขยาย ฯลฯ เราจะทำการใช้การควบคุมปริมาณการส่งต่อเนื่องและกลไกป้องกันการเล่นซ้ำในสภาพแวดล้อมแบบกระจายดังนั้นจึงจำเป็นต้องมีการบันทึกฐานข้อมูล ฉันไม่ได้มองหาการอภิปรายว่านี่เป็นความคิดที่ดีหรือไม่ฉันกำลังมองหาวิธีการที่สามารถทำได้


1
@Kev - ไม่มีมันเป็นบริการสงบดำเนินการโดยใช้ ASP.NET MVC
เกร็กบีช

อาจเป็นไปได้ที่จะใช้ IIS7 และโมดูลเนทิฟ
Daniel Crenna

คุณมีการจัดการที่จะใช้สิ่งนี้หรือไม่? แค่อยากรู้อยากเห็นคุณใช้กลยุทธ์บัฟเฟอร์ใด ๆ เพื่อเขียนไปยัง db หรือไม่?
systempuntoout

1
โครงการที่น่าสนใจ ... ถ้าคุณจบลงด้วยการแก้ปัญหาขั้นสุดท้าย?
PreguntonCojoneroCabrón

คำตอบ:


91

ใช้ a IHttpModuleและ Implement BeginRequestและEndRequestกิจกรรมอย่างแน่นอน

ข้อมูล "ดิบ" ทั้งหมดอยู่ระหว่างHttpRequestและHttpResponseมันไม่ได้อยู่ในรูปแบบดิบเดียว นี่คือส่วนที่จำเป็นในการสร้างการทิ้งขยะสไตล์ฟิดเลอร์ (ใกล้เคียงกับ HTTP ดิบตามที่ได้รับ):

request.HttpMethod + " " + request.RawUrl + " " + request.ServerVariables["SERVER_PROTOCOL"]
request.Headers // loop through these "key: value"
request.InputStream // make sure to reset the Position after reading or later reads may fail

สำหรับการตอบกลับ:

"HTTP/1.1 " + response.Status
response.Headers // loop through these "key: value"

โปรดทราบว่าคุณไม่สามารถอ่านสตรีมการตอบสนองดังนั้นคุณต้องเพิ่มตัวกรองในสตรีมเอาต์พุตและจับสำเนา

ในของBeginRequestคุณคุณจะต้องเพิ่มตัวกรองการตอบกลับ:

HttpResponse response = HttpContext.Current.Response;
OutputFilterStream filter = new OutputFilterStream(response.Filter);
response.Filter = filter;

เก็บfilterที่ซึ่งคุณสามารถไปถึงได้ในEndRequestตัวจัดการ HttpContext.Itemsผมขอแนะนำใน จากนั้นสามารถรับข้อมูลการตอบกลับแบบสมบูรณ์filter.ReadStream()ได้

จากนั้นนำไปOutputFilterStreamใช้โดยใช้รูปแบบของ Decorator เป็น wrapper รอบสตรีม:

/// <summary>
/// A stream which keeps an in-memory copy as it passes the bytes through
/// </summary>
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);
    }
}

1
คำตอบที่ดี หนึ่งความคิดเห็น: คุณพูดว่า "จากนั้นสามารถรับข้อมูลการตอบสนองแบบเต็มในตัวกรอง ToString ()" - คุณไม่ได้หมายถึงตัวกรอง ReadStream ()? (ฉันดำเนินการใน vb.net ไม่ C # แต่ถ้าผมทำงาน ToString ฉันเพิ่งได้รับชื่อชั้นเป็นสตริง .ReadStream ผลตอบแทนการตอบสนองของร่างกายที่ต้องการ..
อดัม

ฉันเห็นด้วยคำตอบที่ดี ฉันใช้มันเป็นพื้นฐานสำหรับคนตัดไม้ที่กำหนดเอง แต่ตอนนี้เจอปัญหาที่บางส่วนขาดหายไปและที่สำคัญที่สุดเมื่อใช้การบีบอัด IIS ฉันไม่สามารถเข้าถึงการตอบสนองการบีบอัดขั้นสุดท้าย ฉันเริ่มคำถามใหม่ที่เกี่ยวข้อง ( stackoverflow.com/questions/11084459/… ) สำหรับเรื่องนี้
Chris

2
ฉันคิดว่า mckamey เป็นอัจฉริยะ คุณสามารถไปทำงานกับ Microsoft เพื่อให้เราเพิ่งได้รับโซลูชันอัจฉริยะแทนที่จะต้องมีวิธีแก้ปัญหาที่ยอดเยี่ยมหรือไม่
ลูกคิด

4
ระวังว่า request.RawUrl อาจทำให้เกิดข้อยกเว้นการตรวจสอบคำขอ ใน 4.5 คุณสามารถใช้ request.Unvalidated.RawUrl เพื่อป้องกันสิ่งนี้ ใน 4.0 ฉันสิ้นสุดโดยใช้การสะท้อนบางอย่างเพื่อเลียนแบบ Request.SaveAs
Freek

1
@mckamey ฉันพยายามใช้โซลูชันของคุณใน global.asax ของฉันด้วย Application_BeginRequest และ Application_EndRequest แต่ฉันไม่แน่ใจว่าฉันควรเขียนรหัสใดใน EndRequest คุณสามารถยกตัวอย่างในคำตอบของคุณได้ไหม?
Jerome2606

48

วิธีการขยายต่อไปนี้ใน HttpRequest จะสร้างสตริงที่สามารถวางลงในไวโอลินและเล่นซ้ำ

namespace System.Web
{
    using System.IO;

    /// <summary>
    /// Extension methods for HTTP Request.
    /// <remarks>
    /// See the HTTP 1.1 specification http://www.w3.org/Protocols/rfc2616/rfc2616.html
    /// for details of implementation decisions.
    /// </remarks>
    /// </summary>
    public static class HttpRequestExtensions
    {
        /// <summary>
        /// Dump the raw http request to a string. 
        /// </summary>
        /// <param name="request">The <see cref="HttpRequest"/> that should be dumped.       </param>
        /// <returns>The raw HTTP request.</returns>
        public static string ToRaw(this HttpRequest request)
        {
            StringWriter writer = new StringWriter();

            WriteStartLine(request, writer);
            WriteHeaders(request, writer);
            WriteBody(request, writer);

            return writer.ToString();
        }

        private static void WriteStartLine(HttpRequest request, StringWriter writer)
        {
            const string SPACE = " ";

            writer.Write(request.HttpMethod);
            writer.Write(SPACE + request.Url);
            writer.WriteLine(SPACE + request.ServerVariables["SERVER_PROTOCOL"]);
        }

        private static void WriteHeaders(HttpRequest request, StringWriter writer)
        {
            foreach (string key in request.Headers.AllKeys)
            {
                writer.WriteLine(string.Format("{0}: {1}", key, request.Headers[key]));
            }

            writer.WriteLine();
        }

        private static void WriteBody(HttpRequest request, StringWriter writer)
        {
            StreamReader reader = new StreamReader(request.InputStream);

            try
            {
                string body = reader.ReadToEnd();
                writer.WriteLine(body);
            }
            finally
            {
                reader.BaseStream.Position = 0;
            }
        }
    }
}

5
รหัสที่ดีมาก! แต่สำหรับการทำงานกับ MVC 4 ฉันต้องเปลี่ยนชื่อคลาสเป็นHttpRequestBaseExtensionsและเปลี่ยนHttpRequestเป็นHttpRequestBaseทุกที่
Dmitry

35

คุณสามารถใช้ตัวแปรเซิร์ฟเวอร์ ALL_RAW เพื่อรับส่วนหัว HTTP ดั้งเดิมที่ส่งมาพร้อมกับคำขอจากนั้นคุณสามารถรับ InputStream ตามปกติ:

string originalHeader = HttpHandler.Request.ServerVariables["ALL_RAW"];

ตรวจสอบ: http://msdn.microsoft.com/en-us/library/ms524602%28VS.90%29.aspx


มันก็ใช้ได้กับฉันเช่นกัน ไม่จำเป็นต้องอยู่ในเครื่องจัดการด้วยซ้ำ ฉันยังสามารถเข้าถึงได้จากหน้า
ช่วย

3
หรือในบริบทเซิร์ฟเวอร์ ASP.NET ให้ใช้: this.Request.ServerVariables ["ALL_RAW"];
Peter Stegnar

ฉันไม่สามารถขอเนื้อความจาก Request ได้อินพุทสตรีมมันจะส่งกลับ "" ทุกครั้ง แต่ ALL_RAW ใช้งานได้ดีในการส่งคืนส่วนหัวของคำขอดังนั้นคำตอบนี้จึงถูกต้องครึ่งหนึ่ง
Justin

1
นอกจากนี้คุณยังสามารถใช้HttpContext.Current.Requestในการคว้านอกบริบทปัจจุบันของตัวควบคุม MVC หน้า ASPX ฯลฯ ... เพียงให้แน่ใจว่ามันไม่ได้เป็นโมฆะแรก;)
jocull

16

ฉันกำลังทำงานในโครงการและอาจไม่ลึกเกินไปบันทึกการใช้พารามิเตอร์ขอ:

ลองดูสิ:

public class LogAttribute : ActionFilterAttribute
{
    private void Log(string stageName, RouteData routeData, HttpContextBase httpContext)
    {
        //Use the request and route data objects to grab your data
        string userIP = httpContext.Request.UserHostAddress;
        string userName = httpContext.User.Identity.Name;
        string reqType = httpContext.Request.RequestType;
        string reqData = GetRequestData(httpContext);
        string controller = routeData["controller"];
        string action = routeData["action"];

        //TODO:Save data somewhere
    }

    //Aux method to grab request data
    private string GetRequestData(HttpContextBase context)
    {
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < context.Request.QueryString.Count; i++)
        {
            sb.AppendFormat("Key={0}, Value={1}<br/>", context.Request.QueryString.Keys[i], context.Request.QueryString[i]);
        }

        for (int i = 0; i < context.Request.Form.Count; i++)
        {
            sb.AppendFormat("Key={0}, Value={1}<br/>", context.Request.Form.Keys[i], context.Request.Form[i]);
        }

        return sb.ToString();
    }

คุณสามารถตกแต่งคลาสคอนโทรลเลอร์ของคุณเพื่อบันทึกได้ทั้งหมด:

[Log]
public class TermoController : Controller {...}

หรือเข้าสู่ระบบเพียงวิธีการกระทำของแต่ละบุคคล

[Log]
public ActionResult LoggedAction(){...}

12

เหตุผลใดที่คุณต้องการเก็บไว้ในรหัสที่จัดการ?

เป็นมูลค่าการกล่าวขวัญว่าคุณสามารถเปิดใช้งานการบันทึกการติดตามล้มเหลวใน IIS7 หากคุณไม่ต้องการคิดค้นวงล้อใหม่ สิ่งนี้จะบันทึกส่วนหัวคำขอและเนื้อหาตอบกลับรวมถึงสิ่งอื่น ๆ อีกมากมาย

การบันทึกการติดตามล้มเหลว


ถ้ามันไม่ใช่ความล้มเหลวล่ะ?
Sinaesthetic

7
คุณสามารถใช้การบันทึกการติดตามล้มเหลวด้วย HTTP 200 ตกลงได้เช่นกันดังนั้นจึงยังไม่สามารถบันทึกความล้มเหลวได้
JoelBellot

2
นี่คือทางออกที่ง่ายที่สุด
Kehlan Krumme

หากต้องการดูการติดตามสแต็กทั้งหมดจำเป็นต้องเพิ่มGlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;เมื่อสิ้นสุดการRegister(..)เข้าWebApiConfig.csใช้
Evgeni Sergeev

8

ฉันไปกับแนวทางของ McKAMEY นี่คือโมดูลที่ฉันเขียนซึ่งจะให้คุณเริ่มต้นและหวังว่าจะช่วยคุณประหยัดเวลา คุณจะต้องเสียบ Logger อย่างชัดเจนด้วยสิ่งที่เหมาะกับคุณ:

public class CaptureTrafficModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(context_BeginRequest);
        context.EndRequest += new EventHandler(context_EndRequest);
    }

    void context_BeginRequest(object sender, EventArgs e)
    {
        HttpApplication app = sender as HttpApplication;

        OutputFilterStream filter = new OutputFilterStream(app.Response.Filter);
        app.Response.Filter = filter;

        StringBuilder request = new StringBuilder();
        request.Append(app.Request.HttpMethod + " " + app.Request.Url);
        request.Append("\n");
        foreach (string key in app.Request.Headers.Keys)
        {
            request.Append(key);
            request.Append(": ");
            request.Append(app.Request.Headers[key]);
            request.Append("\n");
        }
        request.Append("\n");

        byte[] bytes = app.Request.BinaryRead(app.Request.ContentLength);
        if (bytes.Count() > 0)
        {
            request.Append(Encoding.ASCII.GetString(bytes));
        }
        app.Request.InputStream.Position = 0;

        Logger.Debug(request.ToString());
    }

    void context_EndRequest(object sender, EventArgs e)
    {
        HttpApplication app = sender as HttpApplication;
        Logger.Debug(((OutputFilterStream)app.Response.Filter).ReadStream());
    }

    private ILogger _logger;
    public ILogger Logger
    {
        get
        {
            if (_logger == null)
                _logger = new Log4NetLogger();
            return _logger;
        }
    }

    public void Dispose()
    {
        //Does nothing
    }
}

3
คุณไม่สามารถส่งแอพได้อย่างปลอดภัยตอบกลับกรองไปยังสิ่งอื่นที่ไม่ใช่สตรีม HttpModules อื่น ๆ อาจห่อตัวกรองการตอบกลับของคุณด้วยตัวเองและในกรณีนี้คุณจะได้รับการยกเว้นที่ไม่ถูกต้อง
คา Zoltu

ไม่ควรEncoding.UTF8หรือEncoding.Defaultเมื่ออ่านสตรีมคำขอ หรือเพียงแค่ใช้StreamReader( ด้วยการกำจัดคำเตือน )
drzaus

5

ตกลงดังนั้นดูเหมือนว่าคำตอบคือ "ไม่คุณไม่สามารถรับข้อมูลดิบคุณต้องสร้างคำขอ / ตอบกลับจากคุณสมบัติของวัตถุที่แยกวิเคราะห์" โอ้ดีฉันได้ทำสิ่งที่ทันสมัย


3
คุณเห็นความคิดเห็นของ Vineus เกี่ยวกับ ServerVariables ["ALL_RAW"] หรือไม่ ฉันยังไม่ได้ลองด้วยตัวเอง แต่มีการบันทึกไว้เพื่อส่งคืนข้อมูลส่วนหัวแบบดิบที่แม่นยำตามที่ลูกค้าส่งมา แม้ว่าเอกสารจะกลายเป็นผิดและมันกำลังทำการฟื้นฟูใหม่เฮ้การสร้างใหม่ฟรี :-)
Jonathan Gilbert

3

ใช้IHttpModule :

    namespace Intercepts
{
    class Interceptor : IHttpModule
    {
        private readonly InterceptorEngine engine = new InterceptorEngine();

        #region IHttpModule Members

        void IHttpModule.Dispose()
        {
        }

        void IHttpModule.Init(HttpApplication application)
        {
            application.EndRequest += new EventHandler(engine.Application_EndRequest);
        }
        #endregion
    }
}

    class InterceptorEngine
    {       
        internal void Application_EndRequest(object sender, EventArgs e)
        {
            HttpApplication application = (HttpApplication)sender;

            HttpResponse response = application.Context.Response;
            ProcessResponse(response.OutputStream);
        }

        private void ProcessResponse(Stream stream)
        {
            Log("Hello");
            StreamReader sr = new StreamReader(stream);
            string content = sr.ReadToEnd();
            Log(content);
        }

        private void Log(string line)
        {
            Debugger.Log(0, null, String.Format("{0}\n", line));
        }
    }

3
ต่อ Alex และประสบการณ์ของฉันฉันไม่คิดว่าคุณสามารถอ่านได้จาก HttpResponse.OutputStream ดังนั้นวิธีการบันทึกข้อมูลของคุณในวิธีการ ProcessResponse อาจไม่ทำงาน
William Gross

2
วิลเลียมพูดถูก HttpResponse.OutputStream ไม่สามารถอ่านได้ ฉันค้นหาโซลูชันที่ใช้ HttpResponse.Filter และแทนที่สตรีมเอาต์พุตเริ่มต้นด้วยของคุณเอง
Eric Fan Fan

endurasoft.com/blog/post/… async Httpmodule ดีขึ้นไหม
PreguntonCojoneroCabrón

3

ถ้ามีการใช้งานเป็นครั้งคราวเพื่อให้ได้มุมที่รัดกุมแล้วจะมีบางอย่างที่หยาบเหมือนด้านล่างนี้ไหม?

Public Function GetRawRequest() As String
    Dim str As String = ""
    Dim path As String = "C:\Temp\REQUEST_STREAM\A.txt"
    System.Web.HttpContext.Current.Request.SaveAs(path, True)
    str = System.IO.File.ReadAllText(path)
    Return str
End Function

1

คุณสามารถทำได้DelegatingHandlerโดยไม่ต้องใช้ที่OutputFilterกล่าวถึงในคำตอบอื่น ๆ ใน. NET 4.5 โดยใช้Stream.CopyToAsync()ฟังก์ชั่น

ฉันไม่แน่ใจเกี่ยวกับรายละเอียด แต่ไม่ได้เรียกสิ่งเลวร้ายทั้งหมดที่เกิดขึ้นเมื่อคุณพยายามอ่านกระแสการตอบสนองโดยตรง

ตัวอย่าง:

public class LoggingHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        DoLoggingWithRequest(request);
        var response = await base.SendAsync(request, cancellationToken);
        await DoLoggingWithResponse(response);
        return response;
    }

    private async Task DologgingWithResponse(HttpResponseMessage response) {
        var stream = new MemoryStream();
        await response.Content.CopyToAsync(stream).ConfigureAwait(false);     
        DoLoggingWithResponseContent(Encoding.UTF8.GetString(stream.ToArray()));

        // The rest of this call, the implementation of the above method, 
        // and DoLoggingWithRequest is left as an exercise for the reader.
    }
}

0

ฉันรู้ว่ามันไม่ใช่รหัสที่จัดการ แต่ฉันจะแนะนำตัวกรอง ISAPI สองสามปีที่ผ่านมาตั้งแต่ฉันมี "ความสุข" ในการรักษา ISAPI ของฉันเอง แต่จากสิ่งที่ฉันจำได้ว่าคุณสามารถเข้าถึงทุกสิ่งนี้ได้ทั้งก่อนและหลัง ASP.Net ได้ทำสิ่งนี้แล้ว

http://msdn.microsoft.com/en-us/library/ms524610.aspx

หาก HTTPModule ไม่ดีพอสำหรับสิ่งที่คุณต้องการฉันแค่คิดว่าไม่มีวิธีการจัดการใด ๆ ในการทำรายละเอียดตามจำนวนที่ต้องการ มันจะเป็นความเจ็บปวดที่ต้องทำ


0

ฉันเห็นด้วยกับคนอื่น ๆ ใช้ IHttpModule ดูคำตอบของคำถามนี้ซึ่งทำสิ่งเดียวกันกับที่คุณถาม มันบันทึกคำขอและการตอบสนอง แต่ไม่มีส่วนหัว

วิธีการติดตามการร้องขอของ ScriptService WebService


0

การทำสิ่งนี้ให้ดีที่สุดนอกเหนือจากแอปพลิเคชันของคุณ คุณสามารถตั้งค่า reverse proxy เพื่อทำสิ่งนี้ (และอีกมากมาย) พร็อกซีย้อนกลับนั้นเป็นเว็บเซิร์ฟเวอร์ที่อยู่ในห้องเซิร์ฟเวอร์ของคุณและอยู่ระหว่างเว็บเซิร์ฟเวอร์ของคุณและไคลเอนต์ ดู http://en.wikipedia.org/wiki/Reverse_proxy


0

เห็นด้วยกับ FigmentEngine IHttpModuleดูเหมือนจะเป็นวิธีที่จะไป

มองเข้าไปในhttpworkerrequest, และreadentitybodyGetPreloadedEntityBody

ในการรับสิ่งที่httpworkerrequestคุณต้องทำ:

(HttpWorkerRequest)inApp.Context.GetType().GetProperty("WorkerRequest", bindingFlags).GetValue(inApp.Context, null);

ที่inAppเป็นวัตถุ httpapplication


1
ฉันได้กล่าวไปแล้วว่าคำตอบนั้นไม่เหมาะสมเพราะไม่ได้รวบรวมข้อมูลส่วนใหญ่ที่ฉันขอ คำตอบนี้มีประโยชน์อย่างไรบ้าง?
Greg Beech

อธิบายเพิ่มเติม, คำตอบนี้มีประโยชน์อย่างไร?
PreguntonCojoneroCabrón

0

HttpRequestและHttpResponseก่อน MVC เคยมีGetInputStream()และGetOutputStream()ที่สามารถนำมาใช้เพื่อวัตถุประสงค์ที่ ยังไม่ได้ดูในส่วนเหล่านั้นใน MVC ดังนั้นฉันไม่แน่ใจว่าพวกเขามีประโยชน์ แต่อาจเป็นความคิด :)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.