如何记录传出的 HttpClient 请求?
Posted
技术标签:
【中文标题】如何记录传出的 HttpClient 请求?【英文标题】:How to log outgoing HttpClient request? 【发布时间】:2020-10-27 16:52:20 【问题描述】:我想连接到 REST Api,但无论我如何构建请求,它都会不断返回 status code 400 (Bad Request)
。
HttpResponseMessage response = client.PostAsync(url, content).Result;
response.EnsureSuccessStatusCode();
我的问题是,如何调试我的https
请求到服务器?我想看看我的 HTTP 请求是什么样子的。
我尝试使用DiagnosticSource
类,因此我创建了Observer
类并为所有听众订阅它。
观察者
class Observer : IObserver<DiagnosticListener>
public void OnCompleted()
throw new NotImplementedException();
public void OnError(Exception error)
throw new NotImplementedException();
public void OnNext(DiagnosticListener value)
if (value.Name == "HttpHandlerDiagnosticListener")
value.Subscribe(new HttpClientObserver());
HttpClientObserver
class HttpClientObserver : IObserver<KeyValuePair<string, object>>
public void OnCompleted()
throw new NotImplementedException();
public void OnError(Exception error)
throw new NotImplementedException();
public void OnNext(KeyValuePair<string, object> value)
throw new NotImplementedException();
主要
static void Main(string[] args)
DiagnosticListener.AllListeners.Subscribe(new Diagnostic.Observer());
// execute HttpClient methods do not throw any event to Observer
但是没有捕获到任何事件。我错过了什么,HttpClient
是否支持DiagnosticSource
(我如何识别哪些课程?)。我还可以使用什么其他解决方案?
【问题讨论】:
如果您不是在寻找永久固定装置,而只是为了调试此问题,您可以使用 Fiddler 之类的工具来捕获网络流量并查看所有详细信息。 感谢您的提示,但我无法使用这些工具。无论如何,Fiddler 可以检查https
请求吗?
是的,可以。也是邮递员的拦截器。
Burp Suite 还可以跟踪 http/https 流量。
你需要等待 PostAsync。例如 HttpResponseMessage response = await client.PostAsync(url, content);
【参考方案1】:
当您订阅侦听器时,您将创建一个类的新实例。您应该做的是创建一个私有只读实例。 DiagnosticListener 仅限于捕获 HTTP 客户端请求的开始和结束。
下面是一个基本的例子,(代码略有重构)
public static async Task Main(string[] args)
var observer = new HttpClientGlobalListener();
using (var subscription = DiagnosticListener.AllListeners.Subscribe(observer))
var results = await GetMyResultsAsync();
Console.WriteLine(results);
public static async Task<string> GetMyResultsAsync()
var queryString = new StringContent("");
using (HttpClient client = new HttpClient())
HttpResponseMessage response = await client.PostAsync(new Uri("https://example/"), queryString);
//var json = JsonConvert.SerializeObject(response); // You could log response before raising error with "EnsureSuccessStatusCode".
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
return responseBody;
public class HttpClientGlobalListener : IObserver<DiagnosticListener>
private readonly HttpClientInterceptor _interceptor = new HttpClientInterceptor();
public void OnCompleted()
public void OnError(Exception error)
public void OnNext(DiagnosticListener listener)
listener.Subscribe(_interceptor);
public class HttpClientInterceptor : IObserver<KeyValuePair<string, object>>
public void OnCompleted()
public void OnError(Exception error)
public void OnNext(KeyValuePair<string, object> value)
if (value.Key == "System.Net.Http.Desktop.HttpRequestOut.Start")
var requestObj = JsonConvert.SerializeObject(value.Value);
Debug.WriteLine($"Request: requestObj");
else if (value.Key == "System.Net.Http.Desktop.HttpRequestOut.Stop")
var requestObj = JsonConvert.SerializeObject(value.Value);
Debug.WriteLine($"Response: requestObj");
【讨论】:
谢谢,它可以工作 :-) 我现在可以捕获 Request 对象了。但是,我不知道如何将对象转换为我真正发送的raw HTTP Request
,或者如何至少显示我发送的数据(HttpContent
对象)以及raw HTTP Request
中的数据在哪里?跨度>
“value.Value”包含 HTTP 请求。然而,它被包裹在一个动态对象中。我不确定如何查询它。通过使用 Json Serialize,您可以将整个内容存储为字符串并读取它。一个 hacky 解决方案(理论上)是,一旦转换为字符串,您可以删除开始和结束大括号并将其反序列化为 HttpRequest 对象。
我把value.Value
保存到了json文件,没关系。但是json中并没有包含太多的信息,甚至连请求是get或者post等都不包含信息。
不幸的是,json 序列化程序值无法输出所有内容。您可以在调试器中看到所有值。但是我不知道如何查询动态对象。我建议发布另一个问题,特别是“如何将 Value.Value 从对象 f__AnonymousType1以上是关于如何记录传出的 HttpClient 请求?的主要内容,如果未能解决你的问题,请参考以下文章
c#:如何使用 httpclient 发布异步请求并获取流?
新手求助,Arduino联网后,如何回应HttpClient的GET请求