我试图使用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服务器或单声道有关吗?或者是代码本身?
对此有何想法?
答案 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;
}