C# 使用 HttpClient 时记录请求/响应消息

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18924996/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 13:37:27  来源:igfitidea点击:

Logging request/response messages when using HttpClient

c#.netasp.net-mvc-4asp.net-web-api

提问by govin

I have a method that does a POST like below

我有一个方法可以像下面这样进行 POST

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

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

My question is how can I obtain the actual JSON that got posted from the entity object. I would like to log the JSON that gets POSTED, so it will be nice to have that without me having to do a json serialize myself.

我的问题是如何获取从实体对象发布的实际 JSON。我想记录被发布的 JSON,所以不用我自己做一个 json 序列化就可以了。

采纳答案by Kiran Challa

An example of how you could do this:

如何执行此操作的示例:

Some notes:

一些注意事项:

  • LoggingHandlerintercepts the request before it handles it to HttpClientHandlerwhich finally writes to the wire.

  • PostAsJsonAsyncextension internally creates an ObjectContentand when ReadAsStringAsync()is called in the LoggingHandler, it causes the formatter inside ObjectContentto serialize the object and that's the reason you are seeing the content in json.

  • LoggingHandler在处理请求之前拦截请求HttpClientHandler,最终写入线路。

  • PostAsJsonAsync扩展在内部创建一个ObjectContent,当在ReadAsStringAsync()中调用时LoggingHandler,它会导致内部的格式化程序ObjectContent序列化对象,这就是您在 json 中看到内容的原因。

Logging handler:

日志处理程序:

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;
    }
}

Chain the above LoggingHandler with HttpClient:

将上述 LoggingHandler 与 HttpClient 链接起来

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

Output:

输出:

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!"

回答by user1096164

The easiest solution would be to use Wiresharkand trace the HTTP tcp flow.

最简单的解决方案是使用Wireshark并跟踪 HTTP tcp 流。

回答by Rami A.

See http://mikehadlow.blogspot.com/2012/07/tracing-systemnet-to-debug-http-clients.html

http://mikehadlow.blogspot.com/2012/07/tracing-systemnet-to-debug-http-clients.html

To configure a System.Net listener to output to both the console and a log file, add the following to your assembly configuration file:

要将 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>

回答by StuS

Network tracing also available for next objects (see article on msdn)

网络跟踪也可用于下一个对象(请参阅有关msdn 的文章)

  • System.Net.SocketsSome public methods of the Socket, TcpListener, TcpClient, and Dns classes
  • System.NetSome public methods of the HttpWebRequest, HttpWebResponse, FtpWebRequest, and FtpWebResponse classes, and SSL debug information (invalid certificates, missing issuers list, and client certificate errors.)
  • System.Net.HttpListenerSome public methods of the HttpListener, HttpListenerRequest, and HttpListenerResponse classes.
  • System.Net.CacheSome private and internal methods in System.Net.Cache.
  • System.Net.HttpSome public methods of the HttpClient, DelegatingHandler, HttpClientHandler, HttpMessageHandler, MessageProcessingHandler, and WebRequestHandler classes.
  • System.Net.WebSockets.WebSocketSome public methods of the ClientWebSocket and WebSocket classes.
  • System.Net.SocketsSocket、TcpListener、TcpClient 和 Dns 类的一些公共方法
  • System.NetHttpWebRequest、HttpWebResponse、FtpWebRequest 和 FtpWebResponse 类的一些公共方法,以及 SSL 调试信息(无效证书、缺少颁发者列表和客户端证书错误。)
  • System.Net.HttpListenerHttpListener、HttpListenerRequest 和 HttpListenerResponse 类的一些公共方法。
  • System.Net.Cache System.Net.Cache 中的一些私有和内部方法。
  • System.Net.HttpHttpClient、DelegatingHandler、HttpClientHandler、HttpMessageHandler、MessageProcessingHandler 和 WebRequestHandler 类的一些公共方法。
  • System.Net.WebSockets.WebSocketClientWebSocket 和 WebSocket 类的一些公共方法。

Put next lines of code to the configuration file

将下一行代码放入配置文件

<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>