2011-02-04 38 views
6

Tôi có một số mã chạy tốt khi tôi có proxy web được xác định trong Internet Explorer. Tuy nhiên nếu không có định nghĩa nào thì nó không hoạt động. Tôi muốn kiểm tra xem proxy có được xác định không. Làm thế nào tôi có thể thay đổi mã dưới đây để làm điều đó?Cách kiểm tra xem máy chủ proxy có được định cấu hình không?

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; 
} 

Ví dụ: làm cách nào để tải xuống dữ liệu mà không sử dụng proxy?

CẬP NHẬT

Tôi đã thay đổi mã như sau

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; 
} 

tôi nhận được lỗi sau System.NullReferenceException was unhandled by user code trên nếu dòng tuyên bố.

UPDATE 2

Tôi cũng đã cố gắng thay đổi dòng này:

if (!String.IsNullOrEmpty(WebProxy.GetDefaultProxy().Address.AbsoluteUri))

để

if (WebProxy.GetDefaultProxy().Address.AbsoluteUri != null)

nhưng tôi nhận được lỗi này:

System.NullReferenceException: Object reference not set to an instance of an object.

Bất kỳ ý tưởng nào?

+0

Nếu không có proxy: Sẽ bỏ qua 'wc.Proxy = wp;' làm thủ thuật? ("nếu không có proxy, không đặt nó") – Piskvor

+2

Bạn có biết rằng WebProxy.GetDefaultProxy() được coi là lỗi thời? Bạn nên sử dụng WebRequest.GetSystemWebProxy() hoặc WebRequest.DefaultWebProxy thay thế. –

+0

Tôi đã cập nhật câu hỏi của mình để sử dụng 'GetSystemWebProxy'. Vẫn còn gặp khó khăn, bạn có thể xem không? –

Trả lời

10

Hãy nhớ rằng, không có một "địa chỉ proxy" duy nhất hoặc proxy Uri như bạn nghĩ. Thay vào đó, Uri proxy có thể phụ thuộc vào mỗi Uri được lấy ra, như có thể thấy trong hộp thoại Cài đặt Proxy của Internet Explorer.

Internet Explorer - Proxy Settings dialog

Giao diện IWebProxy giúp bạn để có được proxy đúng Uri, và cho bạn biết nếu proxy này sẽ được sử dụng hoặc bỏ qua cho một Uri cụ thể được lấy ra.

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 

Trong phương pháp của bạn, bạn phải chuyển giao giao diện IWebProxy chứ không phải địa chỉ proxy. Giao diện proxy mặc định (như từ GetSystemWebProxy) luôn được đặt làm mặc định.

Nếu bạn muốn đặt proxy đặc biệt của riêng mình trong trường hợp không có proxy được sử dụng cho Uri của bạn, bạn có thể làm như sau ...

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; 
} 
+0

Lưu ý: Không nên gọi cả hai 'IWebProxy.IsBypassed()' và 'IWebProxy.GetProxy()' và mong đợi kết quả là nhất quán, vì cài đặt có thể thay đổi giữa các cuộc gọi. (Đặc biệt là nếu nó xuất phát từ 'WebRequest.GetSystemWebProxy()'.) [Chú thích chia vì các URL dài ...] – antak

+0

Nếu một cuộc gọi đến 'GetProxy()' là bắt buộc, cách duy nhất để xác định một cách an toàn nếu proxy nên được bỏ qua dường như bằng [so sánh kết quả 'Uri' để xem nó có giống với Uri gốc không] (https://referencesource.microsoft.com/#system/net/System/Net/webproxy.cs,598). (ví dụ: 'isBypassed = (webProxy.GetProxy (uri) == uri')) Tuy nhiên điều này [không được ghi lại ở tất cả] (https://msdn.microsoft.com/en-us/library/system.net.iwebproxy .getproxy (v = vs.110) .aspx). – antak

+1

@antak Bạn nói đúng. Mặc dù vấn đề được mô tả có vẻ hơi học vấn với tôi vì cài đặt proxy thường không thay đổi mọi lúc - đặc biệt là không phải mỗi msec. ;) Vì vậy, đối với các trường hợp phổ biến nhất người ta nên được okay. – oleschri

0

Chỉ cần gọi

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

Vâng, tôi đã nghĩ đến việc đó nhưng tôi không chắc cách cấu hình WebClient mà không có proxy. Có ý tưởng nào không? –

0

Bạn có thể sử dụng trình gỡ lỗi và đặt một breakpoint trên câu lệnh if?

Nếu tôi chính xác, cuộc gọi WebProxy.GetDefaultProxy() sẽ trả về giá trị rỗng và do đó là NullReferenceException.

gì sẽ xảy ra nếu bạn thay đổi mã để:

if ((WebProxy.GetDefaultProxy() != null) && (!String.IsNullOrEmpty(WebProxy.GetDefaultProxy().Address.AbsoluteUri))) 

Tôi nghĩ rằng nó nên giải quyết vấn đề của bạn.

+0

Tôi đang cố gắng không sử dụng 'WebProxy.GetDefaultProxy()' vì nó được đánh dấu là lỗi thời kể từ V1. Tôi muốn sử dụng một cái gì đó như 'IWebProxy iwp = WebRequest.GetSystemWebProxy()'. Bất kỳ ý tưởng về làm thế nào để kiểm tra sự tồn tại của một proxy bằng cách sử dụng đó? –

+0

Chỉ cần thử gọi nó là không có proxy được cấu hình. Tôi hy vọng iwp là null, hoặc một ngoại lệ sẽ bị ném. – JochemKempe

+0

Giả định của tôi không chính xác, iwp không phải là null và cũng không phải là ngoại lệ. Tuy nhiên, có thể kiểm tra iwp.IsBypassed (Uri uri) cho uri mục tiêu của bạn mà tôi nghĩ? – JochemKempe

Các vấn đề liên quan