如何将 Fiddler 与 HttpClient 一起使用?

How to use Fiddler with HttpClient?

我知道有很多 questions/answers 博客都在谈论这个,而不是谈论 Telerik 的常见问题解答。我仍然找不到以清晰纯粹的方式诊断和解决这个问题:

上下文:

我有一个 Web API 应用程序,我有一个(单元测试)客户端,它使用 HttpClient 向 API 发送请求。 Web API 应用在 http://localhost:8631/ 中侦听 有时我用Fiddler看看是怎么回事。

问题:

我的 HttpClient 和 Web API 之间的流量未被 Fiddler 捕获。启动Fiddler后流量还可以,但Fiddler中没有显示。

到目前为止的诊断:

结论: 至少我的情况是:这与 HttpClient 是否明确配置为使用 Fiddler 作为代理无关。这是关于 HttpClient 的 and/or Fiddler 的本地主机行为。

再次发出:

有人会问:问题解决了,那问题是什么?嗯...

Q1:这仍然是一个痛苦的问题,因为url在某处编码或配置(我的意思是http://localhost:8631/ http://localhost.fiddler:8631 所以 fiddler 的每次启动和停止都必须更新它。更多:签入源代码控制,并由队友在另一台机器上检出可能会导致问题。所以:有没有更轻松的解决方法?

在团队中工作和使用源代码控制时,硬编码我的机器名称(这也可以工作)会导致同样的痛苦和问题

问题 2: 为什么会出现这种不一致的行为:Pure http://localhost:8631/ 适用于任何浏览器,但不适用于 HttpClient。

我认为回答问题 2 可以使我们更接近于更有用的解决方法。

代码展示

    // Using the following url  w o r k s  regardless of any proxy setting
    // ...but it is a pain to hardcode or configure this and change    depending on Fiddler is running or not

    //private const string ApiUrl = "http://localhost.fiddler:8631/"; 

    // This is not working regardless any proxy setting. Trafic bypasses Fiddler
    private const string ApiUrl = "http://localhost:8631/";

    protected HttpClient GetClient()
    {
        var httpClientHandler = new HttpClientHandler
        {
            // Does not work 
            //Proxy = new WebProxy("http://localhost:8888", false),

            // Does not work
            Proxy = WebRequest.DefaultWebProxy,
            UseProxy = true
        };


        var client = new HttpClient(httpClientHandler)
        {
            BaseAddress = new Uri(ApiUrl)
        };
        // ...

只需为您的 HttpClient 实例定义默认代理,它就可以正常工作。您不必更改代码中的任何 URL。

HttpClientHandler handler = new HttpClientHandler( );
handler.Proxy = WebRequest.DefaultWebProxy;
HttpClient client = new HttpClient( handler as HttpMessageHandler );

我们使用相同的行为没有任何问题(Windows 10,Fiddler4)。

问题是 WebProxy class 的 Microsoft 实现对环回 URL 进行静态检查(基于像 "localhost" 这样的名称列表)并将绕过任何代理对于标识为环回的 uris。即使 BypassProxyOnLocal 设置也无关紧要。此设置仅在您使用本地机器名称或本地网络中的其他机器名称时有效。主机 localhost 或 ip 地址 127.0.0.1 总是被识别为环回,将导致绕过代理。

.net 框架代码的相关部分在WebProxy.IsBypassedManual:

if (host.IsLoopback) {
    return true; // bypass localhost from using a proxy.
}

编写您自己的 WebProxy 后代 class 并将 GetProxyIsBypassed 方法覆盖为 return 使用代理的 uri,即使对于环回网址。然后将 class 的一个实例分配给用于创建 HttpClient.

HttpClientHandler

似乎不​​起作用,因为 .net 代码期望与实现 IAutoWebProxy 的对象一起工作,但 IAutoWebProxy 被声明为内部的,不能在我们自己的代码中使用。

我看到的最简单的解决方案是在运行时使用 ApiUrl 中的本地机器名称替换 "localhost" 的功能。无论 Fiddler 是否为 运行,本地机器名称都将起作用。