在Ubuntu上使用带有Mono的HttpWebResponse清空响应数据

时间:2014-04-07 17:05:41

标签: c# xml ubuntu mono httpwebresponse

我试图使用mono在Ubuntu上运行.NET程序。

程序连接到远程服务器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中获得响应,而是产生了一个空字符串。这是奇怪的,因为没有引发连接错误。

我之前有过使用mono和Ubuntu的经验,但之前没遇到这样的问题。

可能与Ubuntu服务器或单声道有关吗?或者是代码本身?

对此有何想法?

1 个答案:

答案 0 :(得分: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;
}