如何检查代理服务器是否已配置?

7

我有一些代码,在Internet Explorer中定义了Web代理时可以正常运行。但是如果没有定义,它就无法工作。我想检查是否定义了代理。如何更改以下代码以实现此功能?

public DataTable GetCurrentFxPrices(string url)
{
    WebProxy wp = new WebProxy(WebProxy.GetDefaultProxy().Address.AbsoluteUri, true);
    wp.Credentials = CredentialCache.DefaultCredentials;

    WebClient wc = new WebClient();
    wc.Proxy = wp;

    MemoryStream ms = new MemoryStream(wc.DownloadData(url));
    DataSet ds = new DataSet("fxPrices");
    ds.ReadXml(ms);

    DataTable dt = ds.Tables["Rate"];
    int i = dt.Rows.Count;
    return dt;
}

例如,如果不使用代理,我该如何下载数据?
更新
我已将代码更改为以下内容。
public DataTable GetCurrentFxPrices(string url)
{
    WebClient wc = new WebClient();

    if (!String.IsNullOrEmpty(WebProxy.GetDefaultProxy().Address.AbsoluteUri))
    {
        WebProxy wp = new WebProxy(WebProxy.GetDefaultProxy().Address.AbsoluteUri, true);
        wp.Credentials = CredentialCache.DefaultCredentials;
        wc.Proxy = wp;
    }            

    MemoryStream ms = new MemoryStream(wc.DownloadData(url));
    DataSet ds = new DataSet("fxPrices");
    ds.ReadXml(ms);
    DataTable dt = ds.Tables["Rate"];

    int i = dt.Rows.Count;
    return dt;
}

我在if语句行上遇到了以下错误:System.NullReferenceException was unhandled by user code更新2 我也试过更改这一行: if (!String.IsNullOrEmpty(WebProxy.GetDefaultProxy().Address.AbsoluteUri))if (WebProxy.GetDefaultProxy().Address.AbsoluteUri != null) 但我得到了这个错误: System.NullReferenceException: Object reference not set to an instance of an object. 有任何想法?

没有代理:省略 wc.Proxy = wp; 是否可行?(“如果没有代理,就不要设置它”) - Piskvor left the building
2
你知道吗,WebProxy.GetDefaultProxy() 已经被视为过时了吗?你应该使用WebRequest.GetSystemWebProxy() 或 WebRequest.DefaultWebProxy 来代替它。 - Edwin de Koning
我已经更新了我的问题,使用了GetSystemWebProxy。仍然有困难,你能看一下吗? - Mark Allison
我已经尝试对对象进行空值测试,但仍然出现错误。还有其他想法吗,大家? - Mark Allison
3个回答

11

请记住,不存在一个单一的“代理地址”或代理Uri,正如您可能想象的那样。相反,代理Uri可能取决于要检索的每个Uri,如Internet Explorer的代理设置对话框中所示。

Internet Explorer - Proxy Settings dialog

IWebProxy接口帮助您获取正确的代理Uri,并告诉您是否使用此代理或绕过特定要检索的Uri。
using System.Net;

Uri exampleUri = new Uri("http://www.example.org/")

IWebProxy defaultProxy = WebRequest.GetSystemWebProxy();

bool isBypassed = defaultProxy.IsBypassed(exampleUri);
// ... false

Uri proxyUri = defaultProxy.GetProxy(exampleUri);
// ... http://someproxy.mycorp.example:8080

在您的方法中,您需要传递一个IWebProxy接口,而不是代理地址。默认代理接口(例如GetSystemWebProxy)总是设置为默认值。
如果您想在您的Uri没有使用代理的情况下设置自己的特殊代理,您可以按照以下步骤操作...
public DataTable GetCurrentFxPrices(string url)
{
    Uri uri = new Uri(url);

    WebClient webClient = new WebClient();
    IWebProxy defaultProxy = WebRequest.GetSystemWebProxy();

    IWebProxy myProxy = new WebProxy(new Uri("http://myproxy:8080"))
    // if no bypass-list is specified, all Uris are to be retrieved via proxy

    if (defaultProxy.IsBypassed(uri))
    {
        myProxy.Credentials = CredentialCache.DefaultCredentials;
        webClient.Proxy = myProxy;
    }            

    MemoryStream ms = new MemoryStream(webClient.DownloadData(url));
    DataSet ds = new DataSet("fxPrices");
    ds.ReadXml(ms);
    DataTable dt = ds.Tables["Rate"];

    int i = dt.Rows.Count;
    return dt;
}

注意:不应同时调用 IWebProxy.IsBypassed()IWebProxy.GetProxy() 并期望结果一致,因为设置可能在调用之间发生更改。特别是如果它来自 WebRequest.GetSystemWebProxy() - antak
如果需要调用GetProxy(),唯一安全确定代理是否应该被绕过的方法似乎是通过比较结果的Uri是否与原始Uri相同(例如,isBypassed = (webProxy.GetProxy(uri) == uri))。然而,这完全没有记录在文档中 - antak
1
@antak 你说得对。虽然所描述的问题对我来说有点学术化,因为代理设置通常不会一直改变 - 尤其不是每毫秒都改变。;) 因此,对于大多数常见情况,应该是可以的。 - oleschri

0
你能使用调试器,在if语句上打一个断点吗?
如果我没错的话,WebProxy.GetDefaultProxy()调用会返回null,因此引发NullReferenceException。
如果你将代码改为以下内容会发生什么:
if ((WebProxy.GetDefaultProxy() != null) && (!String.IsNullOrEmpty(WebProxy.GetDefaultProxy().Address.AbsoluteUri)))

我认为这应该解决你的问题。


我现在正在尝试不使用WebProxy.GetDefaultProxy(),因为它自V1版本起就被标记为过时了。我想使用类似于IWebProxy iwp = WebRequest.GetSystemWebProxy()的东西。有没有关于如何使用它来测试代理存在性的想法? - Mark Allison
只需尝试在未配置代理的情况下调用它。我期望 iwp 为 null,否则将抛出异常。 - JochemKempe
我的假设是不正确的,iwp既不是null也不会抛出异常。但是,你可以检查iwp.IsBypassed(Uri uri)来检查你的目标uri,我认为这是可能的? - JochemKempe

0

只需调用

if(!String.IsNullOrEmpty(WebProxy.GetDefaultProxy().Address.AbsoluteUri))
{ 
    //do something you want if proxy is set
}
else
{
    //something else(proxy not set)
}

是的,我考虑过那样做,但我不确定如何配置没有代理的WebClient。有什么想法吗? - Mark Allison

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