1

我有一个基于此示例的简单 Web api 项目:http: //aspnet.codeplex.com/sourcecontrol/latest#Samples/WebApi/RelaySample/Program.cs

但是,在上面的示例中,中继正在使用本地服务器,在我的项目中,中继正在使用具有真实地址的外部 Web 服务器;公司X.com

我正在通过浏览器使用中继服务(或 Web 代理服务),例如在浏览器请求 relayService.com/companyX 中。中继服务使用来自外部 companyX.com 站点的数据进行响应。

中继效果很好,但是有些标头不正确,我需要查看 HttpClient 发送到远程 companyX.com 服务器的内容。

在 fiddler 或 Charles 中,只列出了从我的浏览器到 relayService.com 的请求/响应,从 HttpClient 到 relayService.com 的请求/响应永远不会出现。

relayService.com 在我的机器上本地运行,在 IIS7 中,我使用主机文件将流量定向到 relayService.com。

在创建 HttpClient 时,我尝试了以下几种变体:

        var clientHandler = new HttpClientHandler
        {
            CookieContainer = cookies,
            UseCookies = true,
            UseDefaultCredentials = false,
            Proxy = new WebProxy("http://localhost:8888"),
            UseProxy = true,
            AutomaticDecompression = DecompressionMethods.GZip, 
            AllowAutoRedirect = false, 
            ClientCertificateOptions = ClientCertificateOption.Automatic
        };


        HttpClient client = new HttpClient(clientHandler);

更新

如果我更改UseProxy = false了 Fiddler 打开或关闭时服务继续工作。

然后服务将UseProxy = true失败,如果 fiddler 打开,我收到以下错误:

Object reference not set to an instance of an object.

at System.DomainNameHelper.IdnEquivalent(String hostname) at System.Net.HttpWebRequest.GetSafeHostAndPort(Uri sourceUri, Boolean addDefaultPort, Boolean forcePunycode) at System.Net.HttpWebRequest.GenerateProxyRequestLine(Int32 headersSize) at System.Net.HttpWebRequest.SerializeHeaders() at System.Net.HttpWebRequest.EndSubmitRequest() at System.Net.Connection.CompleteConnection(Boolean async, HttpWebRequest request)

随着UseProxy = truefiddler 已关闭,我收到以下(明显)错误:

No connection could be made because the target machine actively refused it 127.0.0.1:8888

在同一个解决方案中,我使用 HttpWebRequest 从网络下载数据,并且确实出现在 Fiddler 中,所以这似乎是 HttpClient.GetAsync() 的问题

我已经在两台机器上尝试过,结果相同。

我整天都在为此苦苦挣扎,任何帮助将不胜感激。

回顾一下:* relayService.com 在我的机器上本地运行,在 IIS7 中

  • 主机文件有“127.0.0.1 relayService.com”

  • relayService.com 是一个 MVC Web API 站点,它使用 HttpClient.GetAsync() 从实时 Web 下载内容

  • Fiddler/Charles 在同一台机器上本地运行

  • 到本地 relayService.com 的浏览器流量出现在 Fiddler/Charles

  • HttpClient.GetAsync() 到实时网络流量不会出现在 Fiddler/Charles 中

  • Fiddler/Charles 都是最新版本。

再次感谢

4

2 回答 2

0

我通过使 HttpClient 静态解决了这个问题。

这很好用(对于程序功能),但上面描述的提琴手有问题,尝试使用代理会引发错误:

private HttpClient _client()
{

    var clientHandler = new HttpClientHandler
    {
        UseCookies = true,
        UseDefaultCredentials = false,
        Proxy = new WebProxy("http://localhost:8888"),
        UseProxy = true,
        AutomaticDecompression = DecompressionMethods.GZip,
        AllowAutoRedirect = true,
        ClientCertificateOptions = ClientCertificateOption.Automatic
    };

    HttpClient client = new HttpClient(clientHandler);
    client.Timeout = TimeSpan.FromMinutes(20);

    return client;
}

客户端是通过以下方式创建的:

using (HttpResponseMessage serviceResponse = await _client().GetAsync(getURL(), HttpCompletionOption.ResponseHeadersRead))
    {
                // Return response

    }

但是,以下方法也有效,所有流量都显示在 Fiddler 中!

private static readonly HttpClientHandler _clientHandler = new HttpClientHandler()
{
    //CookieContainer = cookies,
    UseCookies = true,
    UseDefaultCredentials = false,
    Proxy = new WebProxy("http://localhost:8888"),
    UseProxy = false,
    AutomaticDecompression = DecompressionMethods.GZip,
    AllowAutoRedirect = false,
    ClientCertificateOptions = ClientCertificateOption.Automatic, 
};

//Create a shared instance of HttpClient and set the request timeout
private static readonly HttpClient _client = new HttpClient(_clientHandler)
{
    Timeout = TimeSpan.FromMinutes(20)
};

客户端是使用创建的(唯一的区别是在上面的 _client 之后删除了 '()'):

using (HttpResponseMessage serviceResponse = await _client.GetAsync(getURL(), HttpCompletionOption.ResponseHeadersRead))
    {
                // Return response

    }

我不知道为什么会这样。任何见解将不胜感激。

谢谢,

于 2013-07-26T00:37:26.330 回答
0

如果您使用 Fiddler,您的 HOSTS 文件中不需要任何内容​​;您可以使用 Fiddler 的工具 > HOSTS 将流量重定向到您想要的任何地方。

当尝试从服务帐户(例如 ASP.NET 帐户)捕获流量时,您通常希望将该帐户配置为使用代理;有关详细信息,请参阅http://fiddler2.com/blog/blog/2013/01/08/capturing-traffic-from-.net-services-with-fiddler。如果这样做,则不需要直接在代码中配置代理对象。

您显示的异常表明这是 GenerateProxyRequestLine 函数中的错误。如果你更新这个有什么变化:new WebProxy("http://localhost:8888");new WebProxy("127.0.0.1", 8888);

一般来说,.NET 应用程序会绕过指向 //localhost 或 //127.0.0.1 的 URL 的代理,因此在使用 Fiddler 进行调试时,通常使用 //localhost.fiddler 的服务 URL,以便始终将流量发送到代理。

于 2013-07-25T03:11:46.313 回答