2014-04-07 27 views
1

我試圖在Ubuntu上使用單聲道運行.NET程序。在Ubuntu上使用HttpWebResponse與單聲道的空響應數據

程序連接到遠程服務器API並獲取XML字符串作爲響應。 下面是負責此任務的簡化版本的功能。

using System.Net; 

static string GetProducts(string clientID, string apiKey, string url) 
    { 
     HttpWebRequest req = WebRequest.Create(url) as HttpWebRequest; 
     req.Credentials = new NetworkCredential(clientID, apiKey); 
     req.ContentType = "application/x-www-form-urlencoded"; 

     string result = string.Empty; 

     using (HttpWebResponse resp = req.GetResponse() as HttpWebResponse) 
     { 
      StreamReader reader = new StreamReader(resp.GetResponseStream()); 
      result = reader.ReadToEnd(); 
     } 

     return result; 
    } 

它在我的Windows 8.1機器上工作得非常好。但我的目標是在Ubuntu VPS上運行它。 我正在使用mono來實現這一點。程序運行,但在嘗試解析下載的XML字符串時停止,並出現異常。

[ERROR] FATAL UNHANDLED EXCEPTION: System.Xml.XmlException: Document element did not appear. Line 1, position 1. 

隨着一點點的探索,我發現,該方案實際上沒有得到在XML響應,但產生一個空字符串代替。由於沒有連接錯誤被拋出,這很奇怪。

我已經有一些以前的單聲道和Ubuntu的經驗,但從未遇到過這樣的問題。

它可能是與Ubuntu服務器或單聲道有關嗎?或者是在代碼本身?

對此有何看法?

+0

你可以嘗試像NetTool的進行流量分析Ubuntu和再比較,爲交通,你在窗戶上看到提琴手。也許有一些默認的頭文件/設置需要在linux中顯式設置。 – cgotberg

+0

@cgotberg經過一些測試後,我發現發送的頭文件在windows和ubuntu中有些不同。 在Windows'內容類型:應用程序/ x-WWW窗體-urlencoded 授權:基本MjY2MjQyOmFmNDhlZjUwZDFiM2Y5MWRiZmE5ZTAwYTNjM2ZhNjg3' 在Ubuntu'內容類型:應用程序/ x-WWW窗體-urlencoded 連接:保持alive' 貌似Ubuntu缺少授權行。但我不會在Windows上的任何位置自行設置它。這可以是任何重要的? – Aceonace

+0

這可能是問題所在。這一行設置授權,看起來這是什麼在Ubuntu中不起作用。 req.Credentials = new NetworkCredential(clientID,apiKey);不幸的是,我沒有任何經驗,爲什麼會這樣。可能能夠嘗試類似這種解決方案。 http://stackoverflow.com/a/19851527/1181408 – cgotberg

回答

1

最後我發現問題出在哪裏,並且有些解決方案。首先,我在Perl中編寫了一個簡單的代碼來查看我的問題所在的位置:單聲道或Linux服務器本身。

#!/usr/bin/perl 
use LWP::UserAgent 6; 
my $ClientID = "id"; 
my $APIKey = "key"; 
my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 }); 
my $req = HTTP::Request->new(GET => 'https://server.url'); 
$req->authorization_basic($ClientID, $APIKey); 
my $res = $ua->request($req); 
print "Status: " . $res->status_line . "\n"; 
print "Contents: ". $res->content . "\n"; 

Perl代碼工作,讓我可以確定請求狀態並打印出內容。但爲了讓它工作,我必須禁用服務器安全檢查LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 }),否則它將無法工作。這讓我思考。也許這就是爲什麼我沒有得到我的C#代碼中的任何響應數據。由於安全檢查失敗。進一步測試後,我得到了我的確認,確實是我的情況。我無法找到爲什麼ssl安全檢查失敗,所以我決定完全忽略檢查,就像我在Perl代碼中所做的那樣。我做了一點研究,發現這個線程How to ignore SSL Certificate check。我只是將這段代碼添加到我的函數中,並使其工作。

System.Net.ServicePointManager.ServerCertificateValidationCallback += 
delegate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, 
        System.Security.Cryptography.X509Certificates.X509Chain chain, 
        System.Net.Security.SslPolicyErrors sslPolicyErrors) 
{ 
    return true; // **** Always accept 
}; 

我仍然不知道爲什麼證書檢查在Linux上失敗。但至少,忽略檢查,它可以在Windows和Linux上運行。下面是最終代碼:

using System.Net; 

static string GetProducts(string clientID, string apiKey, string url) 
{ 
    HttpWebRequest req = WebRequest.Create(url) as HttpWebRequest; 
    req.Credentials = new NetworkCredential(clientID, apiKey); 
    req.ContentType = "application/x-www-form-urlencoded"; 

    System.Net.ServicePointManager.ServerCertificateValidationCallback += 
    delegate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, 
        System.Security.Cryptography.X509Certificates.X509Chain chain, 
        System.Net.Security.SslPolicyErrors sslPolicyErrors) 
    { 
     return true; 
    }; 

    string result = string.Empty; 

    using (HttpWebResponse resp = req.GetResponse() as HttpWebResponse) 
    { 
     StreamReader reader = new StreamReader(resp.GetResponseStream()); 
     result = reader.ReadToEnd(); 
    } 

    return result; 
} 
相關問題