我希望我的应用程序访问指定的 HTTPS URL 并从该 URL 下载 CSV 文件。
我有以下代码:
程序.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Security;
using System.IO;
namespace httpWebRequest_Test
{
class Program
{
static void Main(string[] args)
{
var webAddr = "https://SFTP URL/xyz.csv";
var httpWebRequest = (HttpWebRequest) WebRequest.Create(webAddr);
httpWebRequest.ContentType = "text/csv";
httpWebRequest.Method = "POST";
var httpResponse = (HttpWebResponse) httpWebRequest.GetResponse();
//ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);
Stream resStream = httpResponse.GetResponseStream();
}
AcceptAllCertification aac = new AcceptAllCertification();
public static RemoteCertificateValidationCallback AcceptAllCertifications { get; set; }
}
}
接受所有证书.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace httpWebRequest_Test
{
class AcceptAllCertification
{
public bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
return true;
}
}
}
我在编译时没有收到任何错误。但在运行时,我看到以下错误:
底层连接已关闭:无法建立 SSL/TLS 安全通道的信任关系
如何克服这个错误?
编辑1:
我尝试从浏览器访问相同的 URL,它向我显示以下屏幕:
只有添加异常后我才能继续。
编辑2:
在遵循@AndrewSilver 和@Übercoder 的答案后,我看到以下错误:
远程服务器返回错误:(411) 需要长度
此后我添加了
httpWebRequest.ContentLength = 0;
,这导致我出现以下错误:
远程服务器返回错误:(405) 方法不允许。
此后我添加了
httpWebRequest.ContentLength = 100;
,这导致我出现以下错误:
ProtocolViolationException:如果设置 ContentLength>0 或 SendChunked==true,则必须提供请求正文。 通过在 [Begin]GetResponse 之前调用 [Begin]GetRequestStream 来完成此操作。
注意:任何通过提供解决方案来改进我的答案而不绕过证书验证的人都将被标记为已接受。
这段代码对我有用:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
namespace ReadCSVFromURL
{
class Program
{
static void Main(string[] args)
{
SplitCSV();
}
public static string GetCSV(string url)
{
ServicePointManager.ServerCertificateValidationCallback =
(object a, System.Security.Cryptography.X509Certificates.X509Certificate b, System.Security.Cryptography.X509Certificates.X509Chain c, System.Net.Security.SslPolicyErrors d) => { return true; };
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
StreamReader sr = new StreamReader(resp.GetResponseStream());
string results = sr.ReadToEnd();
sr.Close();
return results;
}
public static void SplitCSV()
{
List<string> splitted = new List<string>();
string fileList = GetCSV("URL");
string[] tempStr;
tempStr = fileList.Split(',');
foreach (string item in tempStr)
{
if (!string.IsNullOrWhiteSpace(item))
{
splitted.Add(item);
}
}
}
}
}
更改此行:
ServicePointManager.ServerCertificateValidationCallback =
new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);
对此:
ServicePointManager.ServerCertificateValidationCallback = (a,b,c,d) => { return true;};
您可以删除您拥有的其他代码。您的代码的问题是您引用了您从未设置过的静态
AcceptAllCertifications
。所以它总是有一个空值,这反过来意味着你没有真正给它赋值。
您的证书似乎不受信任。您可以禁用证书验证或使证书受信任(例如,手动将证书放在受信任的根目录下)。