在 Ubuntu 上使用 HttpWebResponse 和 Mono 的空响应数据

本文关键字:Mono 响应 数据 HttpWebResponse Ubuntu | 更新日期: 2023-09-27 17:57:15

我正在尝试使用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上运行它。我正在使用单声道来实现这一点。程序运行,但在尝试分析下载的 XML 字符串时停止并出现异常。

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

通过一些探索,我发现该程序实际上并没有在XML中得到响应,而是生成一个空字符串。这很奇怪,因为没有抛出连接错误。

我以前有一些使用mono和Ubuntu的经验,但以前从未遇到过这样的问题。

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

对此有什么想法吗?

在 Ubuntu 上使用 HttpWebResponse 和 Mono 的空响应数据

最后,我找到了问题所在,并找到了某种解决方案。首先,我用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 代码中所做的那样。我做了一些研究,发现了这个线程如何忽略SSL证书检查。我只是将这段代码添加到我的函数中,它让它工作了。

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