【问题标题】:Accessing HTTPS URL from Console Application using C#使用 C# 从控制台应用程序访问 HTTPS URL
【发布时间】:2016-02-10 07:12:44
【问题描述】:

我希望我的应用程序访问指定的 HTTPS URL 并从该 URL 下载 CSV 文件。

我有以下代码:

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

AcceptAllCertifications.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) Length Required

之后我添加了httpWebRequest.ContentLength = 0;,这导致我出现以下错误:

远程服务器返回错误:(405) Method Not Allowed。

之后我添加了httpWebRequest.ContentLength = 100;,这导致我出现以下错误:

ProtocolViolationException:如果设置 ContentLength>0 或 SendChunked==true,则必须提供请求正文。通过在 [Begin]GetResponse 之前调用 [Begin]GetRequestStream 来执行此操作。

注意:任何通过不绕过证书验证提供解决方案来改进我的答案的人都将被标记为接受。

【问题讨论】:

  • 您是否尝试过从浏览器获取 url 中的文件?它很可能会失败,因为您从中请求文件的服务器没有 SSL 所需的正确证书。
  • @Übercoder 检查我更新的问题
  • 这和SFTP无关,你的问题是关于HTTPS的。
  • @MartinPrikryl 好的。但是我也能用这段代码访问 SFTP URL 吗?还是我必须使用第三方解决方案进行重大更改?
  • 更准确地说,我可以使用HttpWebRequest 访问SFTP URL 吗?

标签: c# url ssl https


【解决方案1】:

这段代码对我有用:

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

通过不绕过证书验证提供解决方案改进此代码的任何人都将被标记为接受。

【讨论】:

  • 这非常有用。休息时也要保持清醒。
【解决方案2】:

改变这一行:

ServicePointManager.ServerCertificateValidationCallback =
     new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);

到这里:

ServicePointManager.ServerCertificateValidationCallback = (a,b,c,d) => { return true;};

你可以摆脱你拥有的其他代码。您的代码的问题在于您引用了您从未设置过的静态AcceptAllCertifications。所以它总是有一个空值,这反过来意味着你没有给它赋值。

【讨论】:

  • 现在抛出“远程服务器返回错误:(411) 长度要求。”在var httpResponse = (HttpWebResponse) httpWebRequest.GetResponse();
【解决方案3】:

您的证书似乎不受信任。您可以禁用证书验证或使证书受信任(例如,手动将证书置于受信任的根目录下)。

SSL Certificate Issue - The remote certificate is invalid according to the validation procedure

【讨论】:

  • 现在抛出“远程服务器返回错误:(411) 长度要求。”在var httpResponse = (HttpWebResponse) httpWebRequest.GetResponse();点击您的回答中提到的链接
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-02
  • 1970-01-01
  • 2016-04-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多