跳转到内容
Guides 4 分钟阅读 1311 次浏览

C# 代理配置

了解如何使用 WebProxy 配置 C# HttpClient,高效管理代理。本指南涵盖配置、身份验证与最佳实践。

C# 代理配置

在 C# 中使用 HttpClient 为 HTTP 请求配置代理,需要实例化一个 HttpClientHandler,将带有代理地址和可选凭据的 WebProxy 对象赋值给它的 Proxy 属性,然后把配置好的 handler 传给 HttpClient 构造函数。这样的配置可以让应用程序把出站网络流量经由中间服务器转发,这对网络安全、访问控制、日志记录或绕过地理限制都是必需的。

理解 HttpClientHttpClientHandlerWebProxy

HttpClient 是 .NET 中发送 HTTP 请求并接收 HTTP 响应的主要类,专为长生命周期实例和并发请求而设计。
HttpClientHandlerHttpClient 发送请求时使用的底层 message handler,它提供网络设置的配置选项,包括代理配置、凭据以及 SSL/TLS 设置。
WebProxy 是用于指定代理服务器 URI 的类,并允许配置代理绕过列表和凭据。

HttpClient 实例管理

HttpClient 实例通常应在多个请求之间复用,以避免套接字耗尽问题。为每个请求创建新的 HttpClient 会导致性能问题和资源枯竭。常见做法是在应用程序的整个生命周期内使用单个 HttpClient 实例,或在 ASP.NET Core 应用中使用 IHttpClientFactory

基本代理配置

要配置基本的 HTTP 或 HTTPS 代理,请创建 HttpClientHandler 实例,将其 Proxy 属性设置为用代理 URI 初始化的新 WebProxy 对象,然后把该 handler 传给 HttpClient 构造函数。

using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;

public class ProxySetup
{
    public static async Task Main(string[] args)
    {
        string proxyAddress = "http://your.proxy.server:8080"; // 替换为您的代理地址
        string targetUrl = "http://httpbin.org/get"; // 用于测试的公共端点

        // 创建 WebProxy 实例
        var webProxy = new WebProxy(proxyAddress, BypassOnLocal: false);

        // 创建 HttpClientHandler 并分配 WebProxy
        var handler = new HttpClientHandler
        {
            Proxy = webProxy,
            UseProxy = true // 显式启用代理
        };

        // 使用配置好的 handler 创建 HttpClient
        using (var httpClient = new HttpClient(handler))
        {
            try
            {
                HttpResponseMessage response = await httpClient.GetAsync(targetUrl);
                response.EnsureSuccessStatusCode(); // 若 HTTP 状态码为错误则抛出异常
                string responseBody = await response.Content.ReadAsStringAsync();
                Console.WriteLine("Request successful. Response snippet:");
                Console.WriteLine(responseBody.Substring(0, Math.Min(responseBody.Length, 500))); // 打印前 500 个字符
            }
            catch (HttpRequestException e)
            {
                Console.WriteLine($"Request error: {e.Message}");
            }
            catch (WebException e)
            {
                Console.WriteLine($"Proxy or network error: {e.Message}");
            }
        }
    }
}

在此示例中:
* WebProxy(proxyAddress, BypassOnLocal: false) 创建一个代理对象。BypassOnLocal: false 确保发往本地地址(例如 localhost)的请求也经过代理,除非之后显式排除。
* handler.UseProxy = true 明确指示 handler 使用已配置的代理。

带身份验证的代理

如果代理服务器需要身份验证(例如用户名和密码),请使用 NetworkCredential 实例设置 WebProxy 对象的 Credentials 属性。

using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;

public class AuthenticatedProxySetup
{
    public static async Task Main(string[] args)
    {
        string proxyAddress = "http://your.authenticated.proxy.server:8080"; // 请替换
        string proxyUsername = "your_username"; // 请替换
        string proxyPassword = "your_password"; // 请替换
        string targetUrl = "http://httpbin.org/get";

        var credentials = new NetworkCredential(proxyUsername, proxyPassword);

        var webProxy = new WebProxy(proxyAddress, BypassOnLocal: false)
        {
            Credentials = credentials
        };

        var handler = new HttpClientHandler
        {
            Proxy = webProxy,
            UseProxy = true
        };

        using (var httpClient = new HttpClient(handler))
        {
            try
            {
                HttpResponseMessage response = await httpClient.GetAsync(targetUrl);
                response.EnsureSuccessStatusCode();
                string responseBody = await response.Content.ReadAsStringAsync();
                Console.WriteLine("Request successful with authenticated proxy.");
                Console.WriteLine(responseBody.Substring(0, Math.Min(responseBody.Length, 500)));
            }
            catch (HttpRequestException e)
            {
                Console.WriteLine($"Request error: {e.Message}");
            }
            catch (WebException e)
            {
                Console.WriteLine($"Proxy or network error: {e.Message}");
            }
        }
    }
}

使用系统默认代理

可以将 HttpClientHandler 配置为使用系统默认代理设置,这些设置通常在操作系统或 Internet Explorer 中配置。在企业环境中这往往是期望的行为。

using System;
using System.Net.Http;
using System.Threading.Tasks;

public class SystemDefaultProxySetup
{
    public static async Task Main(string[] args)
    {
        string targetUrl = "http://httpbin.org/get";

        var handler = new HttpClientHandler
        {
            UseSystemProxy = true // 使用系统默认代理设置
        };

        using (var httpClient = new HttpClient(handler))
        {
            try
            {
                HttpResponseMessage response = await httpClient.GetAsync(targetUrl);
                response.EnsureSuccessStatusCode();
                string responseBody = await response.Content.ReadAsStringAsync();
                Console.WriteLine("Request successful using system default proxy.");
                Console.WriteLine(responseBody.Substring(0, Math.Min(responseBody.Length, 500)));
            }
            catch (HttpRequestException e)
            {
                Console.WriteLine($"Request error: {e.Message}");
            }
            catch (Exception e)
            {
                Console.WriteLine($"Error: {e.Message}");
            }
        }
    }
}

设置 UseSystemProxy = true 会自动将 HttpClientHandler 配置为发现并使用操作系统层面定义的代理设置。若 UseSystemProxytrue,则 Proxy 属性会被忽略。

为特定地址绕过代理

WebProxy 类提供了针对特定地址绕过代理的机制。

BypassProxyOnLocal

WebProxy 构造函数或属性中设置 BypassProxyOnLocal = true,会让本地内网资源不使用代理。这通常是可取的,可避免内部流量不必要地经由外部代理转发。

var webProxy = new WebProxy("http://your.proxy.server:8080")
{
    BypassProxyOnLocal = true // 本地地址不使用代理
};

BypassList

若需要更精细的控制,BypassList 属性允许指定一组正则表达式,用于定义应绕过代理的 URI。

using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;

public class ProxyBypassListSetup
{
    public static async Task Main(string[] args)
    {
        string proxyAddress = "http://your.proxy.server:8080";
        string targetUrl = "http://internal.api.com/data"; // 示例内部 URL
        string externalUrl = "http://external.api.com/data"; // 示例外部 URL

        // 使用正则表达式定义绕过列表
        string[] bypassList = new string[]
        {
            "internal\\.api\\.com", // 绕过 internal.api.com
            "\\.local$" // 绕过所有以 .local 结尾的主机
        };

        var webProxy = new WebProxy(proxyAddress)
        {
            BypassList = bypassList,
            BypassProxyOnLocal = false // 如有需要,通过 BypassList 处理本地绕过
        };

        var handler = new HttpClientHandler
        {
            Proxy = webProxy,
            UseProxy = true
        };

        using (var httpClient = new HttpClient(handler))
        {
            Console.WriteLine($"Attempting request to {targetUrl} (should bypass proxy)...");
            try
            {
                HttpResponseMessage response = await httpClient.GetAsync(targetUrl);
                response.EnsureSuccessStatusCode();
                Console.WriteLine($"Request to {targetUrl} successful. (Check proxy logs if available)");
            }
            catch (HttpRequestException e)
            {
                Console.WriteLine($"Request to {targetUrl} error: {e.Message}");
            }

            Console.WriteLine($"\nAttempting request to {externalUrl} (should use proxy)...");
            try
            {
                HttpResponseMessage response = await httpClient.GetAsync(externalUrl);
                response.EnsureSuccessStatusCode();
                Console.WriteLine($"Request to {externalUrl} successful. (Check proxy logs if available)");
            }
            catch (HttpRequestException e)
            {
                Console.WriteLine($"Request to {externalUrl} error: {e.Message}");
            }
        }
    }
}

HttpClientHandlerSocketsHttpHandler 对比

.NET Core 2.1 引入 SocketsHttpHandler 作为 HttpClient 的默认处理器,提供了更好的性能和跨平台一致性。HttpClientHandler 仍然存在并可显式使用,但新项目通常更推荐 SocketsHttpHandler。使用 SocketsHttpHandler 时,代理配置略有不同。

特性 HttpClientHandler SocketsHttpHandler(推荐用于 .NET Core/.NET 5+)
代理类型 WebProxy IWebProxy(通常是 WebProxy 或自定义实现)
配置方式 WebProxy 实例设置 Proxy 属性。 IWebProxy 实例设置 Proxy 属性。
系统代理 UseSystemProxy = true UseProxy = trueProxy = WebRequest.DefaultWebProxy,或设为 null 以使用系统默认值。
身份验证 WebProxy.Credentials WebProxy.Credentials(若使用 WebProxy
SOCKS 代理 不直接支持。 Proxy 属性设为 new WebProxy("socks5://...") 即可直接支持 SOCKS5
.NET 中的默认值 .NET Framework 的默认处理器。 .NET Core 2.1+ / .NET 5+ 的默认处理器。

使用 SocketsHttpHandler 配置代理

using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;

public class SocketsHttpHandlerProxySetup
{
    public static async Task Main(string[] args)
    {
        string proxyAddress = "http://your.proxy.server:8080";
        string targetUrl = "http://httpbin.org/get";

        var webProxy = new WebProxy(proxyAddress);

        // SocketsHttpHandler 是现代 .NET 的默认处理器,也可显式使用
        var handler = new SocketsHttpHandler
        {
            Proxy = webProxy, // 分配 IWebProxy 实例
            UseProxy = true,  // 显式启用代理
            AllowAutoRedirect = true, // 其他 SocketsHttpHandler 属性示例
            PooledConnectionLifetime = TimeSpan.FromMinutes(5)
        };

        using (var httpClient = new HttpClient(handler))
        {
            try
            {
                HttpResponseMessage response = await httpClient.GetAsync(targetUrl);
                response.EnsureSuccessStatusCode();
                string responseBody = await response.Content.ReadAsStringAsync();
                Console.WriteLine("Request successful using SocketsHttpHandler.");
                Console.WriteLine(responseBody.Substring(0, Math.Min(responseBody.Length, 500)));
            }
            catch (HttpRequestException e)
            {
                Console.WriteLine($"Request error: {e.Message}");
            }
            catch (Exception e)
            {
                Console.WriteLine($"Error: {e.Message}");
            }
        }
    }
}

若要通过 SocketsHttpHandler 使用系统默认代理,请设置 UseProxy = trueProxy = WebRequest.DefaultWebProxy。如果 ProxynullUseProxytrueSocketsHttpHandler 会尝试使用系统默认代理。

错误处理与调试

遇到代理配置问题时,请考虑以下几点:
* 网络连通性:确认应用所在主机能够访问代理服务器。
* 代理服务器状态:确保代理服务器正常运行且配置正确。
* 身份验证:仔细核对代理凭据。凭据错误通常会导致 HTTP 407 Proxy Authentication Required 错误。
* 防火墙规则:检查可能阻断进出代理流量的本地和网络防火墙规则。
* 代理日志:如果可以访问代理服务器日志,请检查其中的连接尝试与错误。
* 异常:捕获 HttpRequestExceptionWebException(用于 .NET Framework 中的 HttpClientHandler)以获取详细的错误信息。

安全注意事项

  • 信任:只通过可信的代理服务器转发流量。恶意代理可能拦截、篡改或记录敏感数据。
  • 凭据:安全地存储代理凭据,避免直接硬编码在源代码中。请使用环境变量、配置文件或密钥管理服务。
  • SSL/TLS:确保代理正确处理 SSL/TLS 流量。如果代理执行 SSL 检查(中间人方式),应用可能需要信任额外的根证书颁发机构。HttpClientHandler 提供 ServerCertificateCustomValidationCallback 属性用于自定义证书校验,但应谨慎使用。
已更新: 03.03.2026
返回分类

试用我们的代理

遍布 100+ 国家的 20,000+ 代理

support_agent
GProxy Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.