从 https URL 下载文件时出现 WebClient 错误
WebClient error when downloading file from https URL
正在尝试从 HTTPS 下载 XML 文件 URL (https://nvd.nist.gov/download/nvd-rss.xml)
此 URL 可通过浏览器公开访问。
在控制台项目中使用 C# Webclient。
但是出现如下异常
using (WebClient client = new WebClient())
{
System.Net.ServicePointManager.SecurityProtocol =
System.Net.SecurityProtocolType.Ssl3;
client.DownloadFile(uri, @"c:\test\nvd-rss.xml");
}
$exception {"The underlying connection was closed: An unexpected error occurred on a send."} System.Net.WebException
尝试将 SSL 等所有属性添加到 system.Net,但没有解决。
试试这个:
using (HttpClient client = new HttpClient())
{
var response = await client.GetAsync("https://nvd.nist.gov/download/nvd-rss.xml");
string xml = await response.Content.ReadAsStringAsync();
//or as byte array if needed
var xmlByteArray = await response.Content.ReadAsByteArrayAsync();
//or as stream
var xmlStream = await response.Content.ReadAsStreamAsync();
//write to file
File.WriteAllBytes(@"c:\temp\test.xml", xmlByteArray)
}
原因是相关站点仅支持 TLS 1.2。在 .NET 中,System.Net.ServicePointManager.SecurityProtocol
的默认值为 Ssl
| Tls
,这意味着 .NET 客户端默认不支持 Tls 1.2(在 SSL 协商期间它不会将此协议列在支持的协议列表中)。至少许多 .NET Framework 版本都是这种情况,不确定是否适用于所有版本。但是 .NET 确实支持 TLS 1.2,要启用它你应该这样做:
string uri = "https://nvd.nist.gov/download/nvd-rss.xml";
using (WebClient client = new WebClient())
{
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
client.DownloadFile(uri, @"c:\test\nvd-rss.xml");
}
你应该没事的。
当然支持多个TLS 1.2协议更好,因为System.Net.SecurityProtocolType是全局设置,并不是所有站点都支持TLS 1.2:
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls | System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls12;
.NET 4.0。 TLS 1.2 不受支持,但如果您的系统上安装了 .NET 4.5(或更高版本),那么您仍然可以选择加入 TLS 1.2,即使您的应用程序框架不支持它。唯一的问题是 .NET 4.0 中的 SecurityProtocolType 没有 TLS1.2 条目,因此我们必须使用此枚举值的数字表示:
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
正在尝试从 HTTPS 下载 XML 文件 URL (https://nvd.nist.gov/download/nvd-rss.xml)
此 URL 可通过浏览器公开访问。
在控制台项目中使用 C# Webclient。
但是出现如下异常
using (WebClient client = new WebClient())
{
System.Net.ServicePointManager.SecurityProtocol =
System.Net.SecurityProtocolType.Ssl3;
client.DownloadFile(uri, @"c:\test\nvd-rss.xml");
}
$exception {"The underlying connection was closed: An unexpected error occurred on a send."} System.Net.WebException
尝试将 SSL 等所有属性添加到 system.Net,但没有解决。
试试这个:
using (HttpClient client = new HttpClient())
{
var response = await client.GetAsync("https://nvd.nist.gov/download/nvd-rss.xml");
string xml = await response.Content.ReadAsStringAsync();
//or as byte array if needed
var xmlByteArray = await response.Content.ReadAsByteArrayAsync();
//or as stream
var xmlStream = await response.Content.ReadAsStreamAsync();
//write to file
File.WriteAllBytes(@"c:\temp\test.xml", xmlByteArray)
}
原因是相关站点仅支持 TLS 1.2。在 .NET 中,System.Net.ServicePointManager.SecurityProtocol
的默认值为 Ssl
| Tls
,这意味着 .NET 客户端默认不支持 Tls 1.2(在 SSL 协商期间它不会将此协议列在支持的协议列表中)。至少许多 .NET Framework 版本都是这种情况,不确定是否适用于所有版本。但是 .NET 确实支持 TLS 1.2,要启用它你应该这样做:
string uri = "https://nvd.nist.gov/download/nvd-rss.xml";
using (WebClient client = new WebClient())
{
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
client.DownloadFile(uri, @"c:\test\nvd-rss.xml");
}
你应该没事的。 当然支持多个TLS 1.2协议更好,因为System.Net.SecurityProtocolType是全局设置,并不是所有站点都支持TLS 1.2:
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls | System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls12;
.NET 4.0。 TLS 1.2 不受支持,但如果您的系统上安装了 .NET 4.5(或更高版本),那么您仍然可以选择加入 TLS 1.2,即使您的应用程序框架不支持它。唯一的问题是 .NET 4.0 中的 SecurityProtocolType 没有 TLS1.2 条目,因此我们必须使用此枚举值的数字表示:
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;