C# 通过代理连接

105
我在一家要求所有连接都通过特定HTTP代理的办公室工作。我需要编写一个简单的应用程序从Web服务器查询一些值-如果没有代理就很容易。如何让C#应用程序支持代理?如何通过代理建立任何类型的连接?
10个回答

122

你可以通过编写代码或在 web.config 或 app.config 中声明来轻松实现此目标。

以下是以编程方式创建代理的示例:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("[ultimate destination of your request]");
WebProxy myproxy = new WebProxy("[your proxy address]", [your proxy port number]);
myproxy.BypassProxyOnLocal = false;
request.Proxy = myproxy;
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse) request.GetResponse();

你基本上是将WebProxy对象分配给request对象的proxy属性。这个request然后将使用你定义的proxy

为了以声明方式实现相同的内容,你可以执行以下操作:

<system.net>
  <defaultProxy>
    <proxy
      proxyaddress="http://[your proxy address and port number]"
      bypassonlocal="false"
    />
  </defaultProxy>
</system.net>

你可以在你的web.config或app.config文件中设置一个默认代理,所有http请求都将使用该代理。根据你需要实现的功能,你可能需要一些额外属性的defaultProxy/proxy元素,请参考相关文档了解详情。


在编程示例中,你为什么没有设置端口? - Skuta
@Skuta - 没有特别的原因。在那个例子中,我仅仅是使用了一个构造函数,它接受URL(作为字符串)和一个布尔值来确定是否绕过本地地址。如果您需要一个特定的端口号,最好使用允许URL(作为字符串)和端口号(作为Int32)的重载构造函数,然后立即设置BypassProxyOnLocal属性为True(如果需要的话)。 - CraigTP
2
@Skuta - 我已经编辑了我的帖子,以澄清这一点,并确保编程和声明性示例实际上正在执行相同的操作! - CraigTP
非常棒的例子。如何在TcpClient中实现同样的效果?我曾经使用TcpClient测试一些连接,但现在我想确保它在代理后仍然能够正常工作。 - kudlatiger

23

如果你正在使用WebClient,它有一个你可以使用的Proxy属性。

正如其他人所提到的,有几种自动化代理设置检测/使用的方法。

Web.Config:

<system.net>
   <defaultProxy enabled="true" useDefaultCredentials="true">
     <proxy usesystemdefault="true" bypassonlocal="true" />
   </defaultProxy>
</system.net>

使用 这篇文章中描述的 WebProxy 类。


你也可以直接配置代理设置(通过代码或者配置文件),这样你的应用程序就会使用这些设置。

Web.Config:

<system.net>
  <defaultProxy>
    <proxy
      proxyaddress="http://[proxy address]:[proxy port]"
      bypassonlocal="false"
    />
  </defaultProxy>
</system.net>

代码:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("url");
WebProxy myproxy = new WebProxy("[proxy address]:[proxy port]", false);
request.Proxy = myproxy;
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse) request.GetResponse();

7
这个一行代码对我来说很有效:
WebRequest.DefaultWebProxy.Credentials = CredentialCache.DefaultNetworkCredentials;

CredentialCache.DefaultNetWorkCredentials 是Internet Explorer中设置的代理设置。

WebRequest.DefaultWebProxy.Credentials 用于应用程序中所有的网络连接。


1
"CredentialCache.DefaultNetWorkCredentials是Internet Explorer中设置的代理设置。这仍然适用吗?我找不到在Internet选项>连接>LAN设置中写用户名和密码的地方。" - Matt
从文档中得知:“对于客户端应用程序,这些通常是运行应用程序的用户的Windows凭据(用户名、密码和域名)。” - Coert Grobbelaar
这个答案可能有点过时了,但我非常确定它对于2015年的Windows是正确的。 - Coert Grobbelaar

7

如果你希望该应用程序使用系统默认代理,将以下内容添加到你的Application.exe.config文件中(其中application.exe是你应用程序的名称):

<system.net>
   <defaultProxy enabled="true" useDefaultCredentials="true">
   <proxy usesystemdefault="true" bypassonlocal="true" />
   </defaultProxy>
</system.net>

更多详细信息可以在System.Net的MSDN文章中找到。


注意: <system.net> 部分应放置在 <configuration> 部分或 exe.config 文件中。这样做可以让我在一个简单的控制台应用程序中使代理工作正常。 - John Dyer

7

尝试使用以下代码,在进行任何http请求之前调用它。该代码将使用您互联网浏览器设置中的代理 - 有一件事情需要注意,我使用 proxy.Credentials = .... 因为我的代理服务器是经过NTLM身份验证的Internet Acceleration Server。尽情体验吧。

static void setProxy()
{
    WebProxy proxy = (WebProxy)WebProxy.GetDefaultProxy();
    if(proxy.Address != null)
    {
        proxy.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
        WebRequest.DefaultWebProxy = new System.Net.WebProxy(proxy.Address, proxy.BypassProxyOnLocal, proxy.BypassList, proxy.Credentials);
    }
}

3
自 .NET Framework 4.5 起,WebProxy.GetDefaultProxy 方法已过时并会返回 null。在使用CredentialCache.DefaultNetworkCredentials之前,请仔细考虑。如果您已将某些凭据放入 CredentialCache 中且您的代理需要此类凭据,则应该能够正常工作。否则它无法帮助您。 - cassandrad

4

Foole的代码对我来说完美运行,但在.NET 4.0中,不要忘记检查代理是否为NULL,这意味着没有配置代理(公司环境之外)。

下面是解决我们公司代理问题的代码:

WebClient web = new WebClient();
if (web.Proxy != null)
    web.Proxy.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;

3

这段代码对我非常有效:

WebClient wc = new WebClient();
wc.Proxy.Credentials = CredentialCache.DefaultCredentials;

0
            var getHtmlWeb = new HtmlWeb() { AutoDetectEncoding = false, OverrideEncoding = Encoding.GetEncoding("iso-8859-2") };

            WebProxy myproxy = new WebProxy("127.0.0.1:8888", false);
            NetworkCredential cred = (NetworkCredential)CredentialCache.DefaultCredentials;
            var document = getHtmlWeb.Load("URL", "GET", myproxy, cred);

5
最好写下对解决方案的说明,而不仅仅是发布代码。你能添加一些文本来帮助读者吗? - Brian Tompsett - 汤莱恩

0
自动代理检测是指系统识别Web代理服务器并用其代表客户端发送请求的过程。该功能也被称为Web代理自动发现(WPAD)。当启用自动代理检测时,系统会尝试查找负责返回可用于请求的代理集合的代理配置脚本。

http://msdn.microsoft.com/en-us/library/fze2ytx2.aspx


4
这如何回答问题?OP如何利用这些信息? - Cullub

0

我将使用一个例子来补充上面的答案。

在尝试通过Web Platform Installer安装软件包时,我遇到了代理问题。

这也使用了一个名为WebPlatformInstaller.exe.config的配置文件。

我尝试了this IIS论坛中建议的修改方法。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>  
  <system.net>    
     <defaultProxy enabled="True" useDefaultCredentials="True"/>      
   </system.net>
</configuration>

并且

<?xml version="1.0" encoding="utf-8" ?>
<configuration>  
   <system.net>    
     <defaultProxy>      
          <proxy 
               proxyaddress="http://yourproxy.company.com:80" 
               usesystemdefault="True"
               autoDetect="False" />    
     </defaultProxy>  
   </system.net>
</configuration>

这些都没有起作用。

对我有用的是这个 -

<system.net>    
    <defaultProxy enabled="true" useDefaultCredentials="false">
      <module type="WebPI.Net.AuthenticatedProxy, WebPI.Net, Version=1.0.0.0, Culture=neutral, PublicKeyToken=79a8d77199cbf3bc" />
    </defaultProxy>  
 </system.net>

需要在 Web 平台安装程序中注册该模块,才能使用它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接