在 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 服务器或单声道有关吗?还是在代码本身中?
对此有什么想法吗?
最后,我找到了问题所在,并找到了某种解决方案。首先,我用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;
}