使用HttpClient时logging请求/响应消息
我有一个方法,像下面这样做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。 我想logging获取POSTED的JSON,所以如果没有我必须做一个JSON序列化我自己,这将是很好的。
一个如何做到这一点的例子:
一些说明:
-
LoggingHandler
在将请求处理到HttpClientHandler
之前拦截该请求,最终写入该LoggingHandler
。 -
PostAsJsonAsync
扩展在内部创build一个ObjectContent
并且在ReadAsStringAsync()
中调用ReadAsStringAsync()
时,会导致ObjectContent
内部的格式化程序序列化对象,这就是您在json中看到内容的原因。
logging处理程序:
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连接上面的LoggingHandler :
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!"
请参阅http://mikehadlow.blogspot.com/2012/07/tracing-systemnet-to-debug-http-clients.html
要将System.Net侦听器configuration为输出到控制台和日志文件,请将以下内容添加到程序集configuration文件中:
<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>
networking跟踪也可用于下一个对象(请参阅MSDN上的文章)
- System.Net.Sockets Socket,TcpListener,TcpClient和Dns类的一些公共方法
- System.Net HttpWebRequest,HttpWebResponse,FtpWebRequest和FtpWebResponse类的一些公共方法,以及SSLdebugging信息(无效证书,缺less颁发者列表和客户端证书错误)。
- System.Net.HttpListener HttpListener,HttpListenerRequest和HttpListenerResponse类的一些公共方法。
- System.Net.Cache System.Net.Cache中的一些私有和内部方法。
- System.Net.Http HttpClient,DelegatingHandler,HttpClientHandler,HttpMessageHandler,MessageProcessingHandler和WebRequestHandler类的一些公共方法。
- System.Net.WebSockets.WebSocket ClientWebSocket和WebSocket类的一些公共方法。
将下一行代码放到configuration文件中
<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>
最简单的解决scheme是使用Wireshark并跟踪HTTP tcpstream。