HttpClient का उपयोग करते समय अनुरोध / प्रतिक्रिया संदेश लॉग करना


114

मेरे पास एक तरीका है जो नीचे की तरह एक POST करता है

var response = await client.PostAsJsonAsync(url, entity);

if (response.IsSuccessStatusCode)
{
        // read the response as strongly typed object
        return await response.Content.ReadAsAsync<T>();
}

मेरा सवाल है कि मैं वास्तविक JSON कैसे प्राप्त कर सकता हूं जो इकाई ऑब्जेक्ट से पोस्ट किया गया है। मैं JSON लॉग इन करना चाहता हूं जो POSTED हो जाता है, इसलिए यह अच्छा होगा कि मेरे बिना खुद को एक जसन सीरियल करना है।

जवाबों:


196

आप यह कैसे कर सकते हैं इसका एक उदाहरण:

कुछ नोट:

  • LoggingHandlerअनुरोध को स्वीकार करता है इससे पहले कि वह इसे संभालता है HttpClientHandlerजो अंत में तार को लिखता है।

  • PostAsJsonAsyncविस्तार आंतरिक रूप से बनाता है ObjectContentऔर जब ReadAsStringAsync()इसे बुलाया जाता है LoggingHandler, तो यह ObjectContentऑब्जेक्ट को क्रमबद्ध करने के लिए फॉर्मेटर के अंदर का कारण बनता है और यही कारण है कि आप सामग्री को जस में देख रहे हैं।

लॉगिंग हैंडलर:

public class LoggingHandler : DelegatingHandler
{
    public LoggingHandler(HttpMessageHandler innerHandler)
        : base(innerHandler)
    {
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        Console.WriteLine("Request:");
        Console.WriteLine(request.ToString());
        if (request.Content != null)
        {
            Console.WriteLine(await request.Content.ReadAsStringAsync());
        }
        Console.WriteLine();

        HttpResponseMessage response = await base.SendAsync(request, cancellationToken);

        Console.WriteLine("Response:");
        Console.WriteLine(response.ToString());
        if (response.Content != null)
        {
            Console.WriteLine(await response.Content.ReadAsStringAsync());
        }
        Console.WriteLine();

        return response;
    }
}

उपरोक्त लॉगिंगहैंडलर को HttpClient के साथ चैन करें :

HttpClient client = new HttpClient(new LoggingHandler(new HttpClientHandler()));
HttpResponseMessage response = client.PostAsJsonAsync(baseAddress + "/api/values", "Hello, World!").Result;

आउटपुट:

Request:
Method: POST, RequestUri: 'http://kirandesktop:9095/api/values', Version: 1.1, Content: System.Net.Http.ObjectContent`1[
[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], Headers:
{
  Content-Type: application/json; charset=utf-8
}
"Hello, World!"

Response:
StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  Date: Fri, 20 Sep 2013 20:21:26 GMT
  Server: Microsoft-HTTPAPI/2.0
  Content-Length: 15
  Content-Type: application/json; charset=utf-8
}
"Hello, World!"

3
यदि आपको अनुरोध विवरण की आवश्यकता है तो यह अच्छा है, लेकिन यह सर्वर को भेजे गए सटीक अनुरोध को प्राप्त करने में विफल रहता है। यदि आपको सर्वर को भेजे गए सभी बाइट की आवश्यकता है, तो यह इस तरह से काम नहीं करेगा।
मैथक

1
क्यों new HttpClientHandler()? यह आधिकारिक डॉक्स में मौजूद नहीं है: docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/…
Zero3

1
आह, यह स्पष्ट रूप से आंतरिक हैंडलर के अशक्त होने के बारे में अपवाद नहीं प्राप्त करने के लिए आवश्यक है ...
3

3
तुम भी ओवरराइड कर सकते हैं MessageProcessingHandler जो मूल रूप से एक कॉल ProcessRequestऔर ProcessResponseपहले और बाद में आप के लिए विधि SendAsyncकॉल।
इल्युसिवब्रियन

1
@ रामी का जवाब नीचे बेहतर है, क्योंकि इसमें कोड परिवर्तन की आवश्यकता नहीं है। एक बार जब आप डीबगिंग कर लेते हैं, तो आप अपने कॉन्फ़िगरेशन से ट्रेसिंग को हटा देते हैं, और यही वह है। नया निर्माण करने की आवश्यकता नहीं है।
त्सही अशेर

50

Http://mikehadlow.blogspot.com/2012/07/tracing-systemnet-to-debug-http-clients.html देखें

कंसोल और लॉग फ़ाइल दोनों के आउटपुट के लिए System.Net श्रोता को कॉन्फ़िगर करने के लिए, अपनी असेंबली कॉन्फ़िगरेशन फ़ाइल में निम्न जोड़ें:

<system.diagnostics>
  <trace autoflush="true" />
  <sources>
    <source name="System.Net">
      <listeners>
        <add name="MyTraceFile"/>
        <add name="MyConsole"/>
      </listeners>
    </source>
  </sources>
  <sharedListeners>
    <add
      name="MyTraceFile"
      type="System.Diagnostics.TextWriterTraceListener"
      initializeData="System.Net.trace.log" />
    <add name="MyConsole" type="System.Diagnostics.ConsoleTraceListener" />
  </sharedListeners>
  <switches>
    <add name="System.Net" value="Verbose" />
  </switches>
</system.diagnostics>

2
यह एक महान समाधान है, कुछ शोध करने और साझा करने के लिए धन्यवाद।
14

यह कैसे काम करता है ? मैं की नकल की <system.diagnostics>में app.configके तहत <configuration>लेकिन में binफ़ोल्डर वहाँ कोई लॉग फ़ाइल और सांत्वना उत्पादन कुछ भी भी प्रदर्शित नहीं करते है, मैं क्या याद आ रही है?
मुफ्लिक्स

1
@ मुफ़्लिक्स, आप उस दस्तावेज़ को पढ़ सकते हैं जो मेरे उत्तर के शीर्ष पर संदर्भित पृष्ठ में जुड़ा हुआ है। मुझे लगता है कि initializeDataविशेषता में निर्दिष्ट फ़ाइल नाम आपके द्वारा चलाए जा रहे निष्पादन योग्य की वर्तमान कार्यशील निर्देशिका में बनाया जाएगा, ताकि आप यह जांचना चाहें कि आपके वातावरण में कौन सा पथ है।
रामी ए।

11

नेटवर्क ट्रेसिंग अगली वस्तुओं के लिए भी उपलब्ध है (देखें msdn पर लेख )

  • System.Net.Socket सॉकेट, TcpListener, TcpClient और Dns वर्गों के कुछ सार्वजनिक तरीके
  • System.Net HttpWebRequest, HttpWebResponse, FtpWebRequest और FtpWebResponse क्लासेस, और SSL डिबग जानकारी (अमान्य प्रमाणपत्र, लापता जारीकर्ता सूची और क्लाइंट प्रमाणपत्र त्रुटियों) के कुछ सार्वजनिक तरीके।
  • System.Net.HttpListener HttpListener, HttpListenerRequest और HttpListenerResponse कक्षाओं की कुछ सार्वजनिक विधियाँ।
  • System.Net.Cache System.Net.Cache में कुछ निजी और आंतरिक तरीके।
  • System.Net.Http HttpClient, DelegatingHandler, HttpClientHandler, HttpMessageHandler, MessageProcessingHandler, और WebRequestandandler वर्गों की कुछ सार्वजनिक विधियाँ।
  • System.Net.WebSockets.WebSocket ClientWebSocket और WebSocket कक्षाओं के कुछ सार्वजनिक तरीके।

कॉन्फ़िगरेशन फ़ाइल में कोड की अगली पंक्तियाँ डालें

<configuration>  
  <system.diagnostics>  
    <sources>  
      <source name="System.Net" tracemode="includehex" maxdatasize="1024">  
        <listeners>  
          <add name="System.Net"/>  
        </listeners>  
      </source>  
      <source name="System.Net.Cache">  
        <listeners>  
          <add name="System.Net"/>  
        </listeners>  
      </source>  
      <source name="System.Net.Http">  
        <listeners>  
          <add name="System.Net"/>  
        </listeners>  
      </source>  
      <source name="System.Net.Sockets">  
        <listeners>  
          <add name="System.Net"/>  
        </listeners>  
      </source>  
      <source name="System.Net.WebSockets">  
        <listeners>  
          <add name="System.Net"/>  
        </listeners>  
      </source>  
    </sources>  
    <switches>  
      <add name="System.Net" value="Verbose"/>  
      <add name="System.Net.Cache" value="Verbose"/>  
      <add name="System.Net.Http" value="Verbose"/>  
      <add name="System.Net.Sockets" value="Verbose"/>  
      <add name="System.Net.WebSockets" value="Verbose"/>  
    </switches>  
    <sharedListeners>  
      <add name="System.Net"  
        type="System.Diagnostics.TextWriterTraceListener"  
        initializeData="network.log"  
      />  
    </sharedListeners>  
    <trace autoflush="true"/>  
  </system.diagnostics>  
</configuration>  

-14

सबसे आसान समाधान Wireshark का उपयोग करना और HTTP tcp प्रवाह का पता लगाना होगा।


9
एक ऐसी दुनिया की कल्पना करें जहां इस प्रकार के अधिकांश कनेक्शन वास्तव में HTTPS हैं।
झल्लाहट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.