ASP.NET MVC এবং IIS7 এ কাঁচা HTTP অনুরোধ / প্রতিক্রিয়া লগ করা হচ্ছে


140

আমি একটি ওয়েব সার্ভিস লিখছি (এএসপি.নেট এমভিসি ব্যবহার করে) এবং সহায়তার প্রয়োজনের জন্য আমরা অনুরোধগুলি এবং প্রতিক্রিয়াটিকে যতটা সম্ভব কাঁচা, তারের অন বিন্যাসের (যেমন এইচটিটিপি সহ) লগতে সক্ষম হতে চাই পদ্ধতি, পথ, সমস্ত শিরোলেখ এবং বডি) একটি ডাটাবেসে প্রবেশ করুন।

আমি যে বিষয়ে নিশ্চিত নই তা ন্যূনতম 'ম্যাংলেড' উপায়ে কীভাবে এই ডেটাটি ধরে রাখা যায়। আমি বিশ্বাস করি যে অনুরোধটি HttpRequestবস্তুর সমস্ত বৈশিষ্ট্য পরীক্ষা করে এবং সেগুলি থেকে একটি স্ট্রিং তৈরি করে (এবং একইভাবে প্রতিক্রিয়ার জন্য) যা দেখায় তাতে আমি পুনরায় গঠন করতে পারি তবে আমি সত্যিকারের অনুরোধ / প্রতিক্রিয়া ডেটা ধরে রাখতে চাই তারে প্রেরণ।

ফিল্টার, মডিউল ইত্যাদির মতো যে কোনও বাধা ব্যবস্থা ব্যবহার করতে পেরে আমি খুশি এবং সমাধানটি আইআইএস 7-র সাথে সুনির্দিষ্ট হতে পারে। তবে, আমি এটি কেবল পরিচালিত কোডেই রাখতে পছন্দ করি।

কোন সুপারিশ?

সম্পাদনা: আমি নোট করেছি যে HttpRequestএকটি SaveAsপদ্ধতি আছে যা ডিস্কে অনুরোধ সংরক্ষণ করতে পারে তবে এটি অভ্যন্তরীণ রাষ্ট্র থেকে অনুরোধটিকে পুনরায় গঠন করে যে কোনও অভ্যন্তরীণ সহায়ক পদ্ধতি ব্যবহার করা যায় না যা সর্বজনীনভাবে অ্যাক্সেস করা যায় না (বেশিরভাগ ক্ষেত্রেই এটি কোনও ব্যবহারকারীর দ্বারা সরবরাহিতগুলিতে সংরক্ষণের অনুমতি দেয় না) স্ট্রিম আমি জানি না)। সুতরাং এটি দেখতে শুরু হচ্ছে যে আমি অবজেক্টগুলি থেকে অনুরোধ / প্রতিক্রিয়া পাঠ্যের পুনর্গঠন করার জন্য আমার সর্বোত্তম চেষ্টা করতে হবে ... হাহাকার।

সম্পাদনা 2: দয়া করে নোট করুন যে আমি পদ্ধতি, পথ, শিরোনামগুলি সহ পুরো অনুরোধটি বলেছিলাম বর্তমান প্রতিক্রিয়াগুলি কেবলমাত্র শরীরের স্ট্রিমগুলিতে নজর রাখে যা এই তথ্যগুলিকে অন্তর্ভুক্ত করে না।

3 সম্পাদনা করুন: কেউ কি এখানে প্রায় প্রশ্ন পড়েন না? পাঁচটি উত্তর এখনও পর্যন্ত এবং এখনও কোনওটি তার পথে সম্পূর্ণ কাঁচা পাওয়ার জন্য কোনওভাবেও ইঙ্গিত দেয় না। হ্যাঁ, আমি জানি যে আমি আউটপুট স্ট্রিমগুলি এবং শিরোনামগুলি এবং ইউআরএল এবং অনুরোধের বস্তু থেকে সমস্ত স্টাফ ক্যাপচার করতে পারি। আমি ইতিমধ্যে প্রশ্নে বলেছি যে দেখুন:

এইচটিটিপিআরকুয়েস্ট অবজেক্টের সমস্ত বৈশিষ্ট্য পরীক্ষা করে এবং সেগুলি থেকে একটি স্ট্রিং তৈরি করে (এবং একইভাবে প্রতিক্রিয়ার জন্য) আমি অনুরোধটি দেখে মনে হচ্ছে তার পুনরায় গঠন করতে পারি তবে সত্যিকারের অনুরোধ / প্রতিক্রিয়া ডেটা ধরে রাখতে আমি সত্যিই চাই যে তারে প্রেরণ করা হয়।

আপনি যদি সম্পূর্ণ কাঁচা ডেটা জানেন (সহ শিরোনাম, ইউআরএল, এইচটিপি পদ্ধতি ইত্যাদি) সহজেই পুনরুদ্ধার করা যায় না তবে তা জানার পক্ষে দরকারী। একইভাবে আপনি যদি এটি কীভাবে কাঁচা ফর্ম্যাটে (হ্যাঁ, আমি এখনও শিরোনাম, ইউআরএল, এইচটিপি পদ্ধতি ইত্যাদির অর্থ বোঝাতে চাই) এটি পুনর্গঠন না করেই জানতে পারি, যা আমি জিজ্ঞাসা করেছি, তবে এটি খুব কার্যকর হবে। তবে আমি HttpRequest/ HttpResponseবস্তুগুলি থেকে এটি পুনর্গঠন করতে পারি তা বলাই কার্যকর নয়। আমি জানি। আমি ইতিমধ্যে এটি বলেছি।


দয়া করে নোট করুন: কেউ এটিকে খারাপ ধারণা বলে শুরু করার আগে বা স্কেল্যাবিলিটি ইত্যাদিকে সীমাবদ্ধ রাখার আগে আমরা বিতরণ পরিবেশে থ্রোটলিং, সিক্যুয়াল ডেলিভারি এবং অ্যান্টি-রিপ্লে পদ্ধতিগুলিও প্রয়োগ করব, সুতরাং যেভাবেই ডাটাবেস লগিং প্রয়োজন। আমি এটি একটি ভাল ধারণা কিনা তা নিয়ে কোনও আলোচনার খোঁজ করছি না, আমি কীভাবে এটি করা যায় তা সন্ধান করছি।


1
@ কেভ - না, এটি এএসপি.নেট এমভিসি
গ্রেগ বিচ

এটা তোলে IIS7 এবং একটি নেটিভ মডিউল ব্যবহার করে কি সম্ভব সম্ভবত নেই - msdn.microsoft.com/en-us/library/ms694280.aspx
ড্যানিয়েল Crenna

আপনি কি এটি বাস্তবায়ন করতে পেরেছেন? শুধু কৌতূহলী, আপনি ডিবিতে কোনও বাফার কৌশল অবলম্বন করেছিলেন?
সিস্টেমে

1
আকর্ষণীয় প্রকল্প ... আপনি যদি চূড়ান্ত সমাধান দিয়ে শেষ না করেন?
প্রিগান্টনকোজনিরো ক্যাব্রন

উত্তর:


91

নিশ্চিতভাবে একটি ব্যবহার IHttpModuleএবং বাস্তবায়ন BeginRequestএবংEndRequest ইভেন্টগুলি ।

সমস্ত "কাঁচা" ডেটা উপস্থিত রয়েছে HttpRequestএবং HttpResponseএটি কোনও একক কাঁচা বিন্যাসে নেই। ফিডলার-স্টাইলের ডাম্পগুলি তৈরি করার জন্য প্রয়োজনীয় অংশগুলি এখানে রয়েছে (কাঁচা এইচটিটিপি এটি যতটা কাছে আসে তার কাছাকাছি):

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একটি স্ট্রিমের চারপাশে মোড়ক হিসাবে ডেকোরেটর প্যাটার্ন ব্যবহার করে প্রয়োগ করুন :

/// <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
চমৎকার উত্তর. যদিও একটি মন্তব্য: আপনি বলেছিলেন "সেখানে ফিল্টারটিতে সম্পূর্ণ প্রতিক্রিয়া ডেটা পাওয়া যাবে o টুস্ট্রিং ()।" -আপনি কি ফিল্টার মানে না? রিড স্ট্রিম ()? (আমি vb.net মধ্যে বাস্তবায়ন করছি গ না # কিন্তু যদি আমি ToString আমি শুধু একটি স্ট্রিং হিসেবে বর্গ নাম পেতে .ReadStream পছন্দসই প্রতিক্রিয়া শরীর ফেরৎ
আদম

আমি সম্মত, ভাল উত্তর। আমি এটি একটি কাস্টম লগারের ভিত্তি হিসাবে ব্যবহার করেছি তবে এখন এমন একটি সমস্যা দেখা দিয়েছে যেখানে কয়েকটি শিরোনাম অনুপস্থিত এবং IIS সংক্ষেপণটি ব্যবহার করার সময় আমি চূড়ান্ত সংক্ষেপিত প্রতিক্রিয়াটি অ্যাক্সেস করতে পারি না। আমি এটির জন্য একটি নতুন সম্পর্কিত প্রশ্ন ( স্ট্যাকওভারফ্লো . com / প্রশ্নস / ১১১০৮৪৫৯৯/২ ) শুরু করেছি ।
ক্রিস

2
আমি মনে করি ম্যাকামে একজন প্রতিভা। আপনি কি মাইক্রোসফ্টের পক্ষে কাজ করতে পারেন যাতে আমরা কেবলমাত্র উজ্জ্বল ওয়ার্কআউন্ডসের প্রয়োজনের পরিবর্তে বুদ্ধিমান সমাধান পেতে পারি?
অ্যাবাকাস 17

4
অনুরোধ থেকে সাবধান থাকুন.রাউআরএল একটি অনুরোধ বৈধতা ব্যতিক্রম ট্রিগার করতে পারে। 4.5 এ আপনি অনুরোধটি ব্যবহার করতে পারেন nঅনুযুক্ত। 4.0 আমি আপ অনুকরণমূলক Request.SaveAs কিছু প্রতিফলন ব্যবহার শেষ হয়ে
Freek

1
@ এমকামে আমি আমার গ্লোবাল.অ্যাক্সে অ্যাপ্লিকেশন_বেগিনরেয়েস্ট এবং অ্যাপ্লিকেশন_এন্ডরয়েস্টের সাহায্যে আপনার সমাধানটি প্রয়োগ করার চেষ্টা করি তবে আমি নিশ্চিত নই যে এন্ড্রয়েউয়েস্টে আমার কোন কোডটি লিখতে হবে, আপনি কি আপনার উত্তর প্লিজটিতে একটি উদাহরণ দিতে পারবেন?
জেরোম 2606

48

এইচটিটিপিআরকুয়েস্টের নীচের এক্সটেনশন পদ্ধতিটি এমন একটি স্ট্রিং তৈরি করবে যা ফিডলারের মধ্যে আটকানো এবং পুনরায় খেলতে পারা যায়।

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
খুব ভাল কোড! তবে এটির জন্য এমভিসি 4 এর সাথে কাজ করার জন্য আমাকে ক্লাসের নামটি HttpRequestBaseExtensionsপরিবর্তন HttpRequestকরতে HttpRequestBaseহয়েছিল এবং প্রতি জায়গায় পরিবর্তন করতে হয়েছিল।
দিমিত্রি

35

অনুরোধের সাথে মূল HTTP শিরোনাম প্রেরণের জন্য আপনি ALL_RAW সার্ভার ভেরিয়েবলটি ব্যবহার করতে পারেন, তবে আপনি যথারীতি ইনপুট স্ট্রিম পেতে পারেন:

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

চেক আউট: http://msdn.microsoft.com/en-us/library/ms524602%28VS.90%29.aspx


এটি আমার জন্যও কাজ করেছিল। এমনকি কোনও হ্যান্ডলারের মধ্যে থাকার দরকারও ছিল না। আমি পৃষ্ঠাটি থেকে এখনও এটি অ্যাক্সেস করতে সক্ষম হয়েছি।
হেলিফ্যান্ট

3
বা এএসপি.এনইটি সার্ভারের প্রসঙ্গে, এইটি ব্যবহার করুন: অনুসন্ধান করুন e সার্ভারে ভেরিয়েবলস ["ALL_RAW"];
পিটার স্টিগনার

আমি অনুরোধের বডিটি রিকুয়েস্ট থেকে পেতে পারছি না। ইনপুট স্ট্রিম, এটি প্রতিবার "" ফিরিয়ে দেয়, তবে ALL_RAW অনুরোধ শিরোনাম ফিরিয়ে দেওয়ার জন্য দুর্দান্ত কাজ করে তাই এই উত্তরটি অর্ধেক ঠিক।
জাস্টিন 22

1
আপনি HttpContext.Current.Requestএমভিসি কন্ট্রোলার, এএসপিএক্স পৃষ্ঠাগুলি ইত্যাদির বাইরে বর্তমান প্রসঙ্গটি ধরতেও ব্যবহার করতে পারেন ... এটি নিশ্চিত করুন যে এটি প্রথমে বাতিল নয়;)
জোকুল

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

কোনও ব্যবস্থাপনার কোডে রাখার দরকার নেই?

এটি উল্লেখযোগ্য যে আপনি চাকাটি পুনরায় উদ্ভাবন করতে পছন্দ না করলে আপনি আইআইএস 7 এ ব্যর্থ ট্রেস লগিং সক্ষম করতে পারবেন । এই শিরোনামগুলি, অনুরোধ এবং প্রতিক্রিয়া বডি পাশাপাশি অনেকগুলি জিনিস লগ করে।

ট্রেস লগিং ব্যর্থ


যদি এটি ব্যর্থতা না হয়?
সিনায়েস্টিক

7
আপনি এইচটিটিপি 200 এর সাথেও ব্যর্থ ট্রেস লগিং ব্যবহার করতে পারেন, তাই অ-ব্যর্থতাগুলি এখনও লগ করা যায়
জোয়েলবেলট

2
এটি এখন পর্যন্ত সবচেয়ে সহজ সমাধান।
কেহলান ক্রুমমে

পুরো স্ট্যাক ট্রেসটি দেখতে GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;, Register(..)ইন- এর শেষে যুক্ত করা দরকার ছিল WebApiConfig.cs, তবে এটি সংস্করণগুলির মধ্যে পৃথক হতে পারে।
এভেজেনি সার্জিভ

8

আমি ম্যাকমেয়ির পদ্ধতির সাথে গেলাম। এখানে আমি লিখেছি এমন একটি মডিউল যা আপনাকে শুরু করবে এবং আশা করি আপনি কিছুটা সময় সাশ্রয় করবেন। আপনাকে অবশ্যই এমন কিছু দিয়ে লগারকে প্লাগ করতে হবে যা আপনার জন্য কাজ করে:

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
আপনি কোনও অ্যাপ্লিকেশনটি নিরাপদে কাস্ট করতে পারবেন না es অন্যান্য এইচটিপিএমডিউলগুলি আপনার প্রতিক্রিয়া ফিল্টারটি তাদের নিজের সাথে মোড়তে পারে এবং এই ক্ষেত্রে আপনি একটি অবৈধ .ালাই ব্যতিক্রম পাবেন।
মিকাহ জোল্টু

এটি হওয়া উচিত নয় Encoding.UTF8, বা Encoding.Defaultঅনুরোধের স্ট্রিমটি পড়ার সময়? অথবা কেবলমাত্র একটি ব্যবহার করুন StreamReader(
ক্যাভিয়েট

5

ঠিক আছে, সুতরাং দেখে মনে হচ্ছে উত্তরটি "না আপনি কাঁচা ডেটা পেতে পারেন না, আপনাকে পার্স করা বস্তুর বৈশিষ্ট্য থেকে অনুরোধ / প্রতিক্রিয়াটি পুনর্গঠন করতে হবে"। ওহ ভাল, আমি পুনর্নির্মাণের কাজটি করেছি।


3
সার্ভারভেরিয়েবলস ["ALL_RAW"] সম্পর্কে ভাইনাসের মন্তব্য আপনি দেখেছেন? আমি এখনও এটি চেষ্টা করে দেখিনি, তবে ক্লায়েন্টের পাঠানো হিসাবে কাঁচা শিরোনামের তথ্যটি যথাযথভাবে ফেরত দেওয়ার নথিযুক্ত is এমনকি যদি দস্তাবেজটি ভুল হিসাবে দেখা দেয় এবং এটি পুনর্গঠন করে চলেছে, আরে, নিখরচায় পুনর্গঠন :-)
জোনাথন গিলবার্ট

3

একটি আইএইচটিটিপিডি ব্যবহার করুন :

    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
অ্যালেক্স এবং আমার নিজের অভিজ্ঞতা অনুসারে, আপনি HTTPResponse থেকে পড়তে পারেন বলে মনে করি না ut
উইলিয়াম গ্রস

2
উইলিয়াম ঠিক বলেছেন। এইচটিপিআরস্পোনস.আউটপুট স্ট্রিমটি পঠনযোগ্য নয়। আমি একটি সমাধান খুঁজে পাচ্ছি যা HTTPResponse ব্যবহার করতে হয় il ফিল্টার এবং আপনার নিজের সাথে ডিফল্ট আউটপুট স্ট্রিমটি প্রতিস্থাপন করুন।
এরিক ফ্যান


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

ফাংশনটি ব্যবহার করে .NET 4.5 এ অন্য উত্তরগুলিতে উল্লিখিত DelegatingHandlerব্যবহার না করে আপনি এটি সম্পাদন করতে পারেন ।OutputFilterStream.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

আমি জানি এটি পরিচালিত কোড নয়, তবে আমি একটি ইসাপি ফিল্টার প্রস্তাব করতে চলেছি। আমার নিজের আইএসপিআই বজায় রাখার "আনন্দ" পেয়েছি তার কয়েক বছর হয়ে গেছে তবে আমি যা মনে করি তা থেকে আপনি এএসপি এর আগে এবং পরে উভয়ই এই সমস্ত জিনিসটিতে অ্যাক্সেস পেতে পারেন। নেট এটি কাজ করেছে।

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

যদি কোনও HTTPModule আপনার প্রয়োজনীয়তার জন্য যথেষ্ট ভাল না হয় তবে আমি কেবলমাত্র প্রয়োজনীয় পরিমাণে বিশদে এটি করার কোনও পরিচালিত উপায় আছে বলে মনে করি না। যদিও এটি করতে ব্যথা হবে।


0

আমি অন্যদের সাথে একমত, IHttpModule ব্যবহার করুন। এই প্রশ্নের উত্তরটি একবার দেখুন, যা আপনি যা জিজ্ঞাসা করছেন প্রায় একই কাজ করে। এটি অনুরোধ এবং প্রতিক্রিয়া লগ, কিন্তু শিরোনাম ছাড়া।

কীভাবে স্ক্রিপ্ট সার্ভিস ওয়েব সার্ভিসেস অনুরোধগুলি ট্রেস করবেন?


0

আপনার আবেদনের বাইরে এটি করা ভাল। এই জাতীয় (এবং আরও অনেক কিছু) করতে আপনি একটি বিপরীত প্রক্সি সেট আপ করতে পারেন। একটি বিপরীত প্রক্সি মূলত একটি ওয়েব সার্ভার যা আপনার সার্ভার ঘরে বসে এবং আপনার ওয়েব সার্ভার (গুলি) এবং ক্লায়েন্টের মাঝে দাঁড়িয়ে। Http://en.wikedia.org/wiki/Revers_proxy দেখুন


0

ফিগমেন্টইঞ্জিনের সাথে সম্মত হন, IHttpModuleযাবার উপায় বলে মনে হচ্ছে।

দেখুন httpworkerrequest, readentitybodyএবং GetPreloadedEntityBody

এটি পেতে আপনার এটি httpworkerrequestকরতে হবে:

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

inAppHTTP অ্যাপ্লিকেশন অবজেক্টটি কোথায় ।


1
আমি ইতিমধ্যে বলেছি যে উত্তরটি উপযুক্ত নয় কারণ এটি আমার কাছে বলা বেশিরভাগ তথ্য ক্যাপচার করে না। এই উত্তরটি কোনও উপায়ে কীভাবে সহায়ক?
গ্রেগ বিচ

আরও ব্যাখ্যা করুন, কোনওভাবে এই উত্তর কীভাবে সহায়ক?
প্রিগান্টনকোজনিরো ক্যাব্রন

0

HttpRequestএবং HttpResponseপ্রাক এমভিসির একটি ছিল GetInputStream()এবং GetOutputStream()এটি সেই উদ্দেশ্যে ব্যবহার করা যেতে পারে। এমভিসি-র অংশগুলি সন্ধান করেননি তাই আমি নিশ্চিত নই যে তারা এভায়াভলে তবে এটি একটি ধারণা হতে পারে :)

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.