C# WebClient DownloadFile 只工作一次
C# WebClient DownloadFile works only once
我构建了一个功能,可以从我的网站(.NET 网络表单、旧应用程序)下载一系列报告,将它们另存为临时文件夹中的 .html 文件,压缩它们并 return给用户的存档。
该应用程序使用 windows 身份验证,我通过启用
设法在请求中传递了当前用户凭据
Credentials = CredentialCache.DefaultCredentials
一切都在我的开发环境中无缝运行(在 IIS Express 和 IIS 中),但在生产服务器(Windows 服务器 2008 R2,IIS 7.5)上,它仅在我将周期限制为一次迭代时才有效只要。
看起来 WebClient 底层连接保持打开状态,服务器拒绝在下一个周期打开另一个连接。
我收到的错误消息是
The request was aborted: Could not create SSL/TLS secure channel.
并且,启用 WCF 跟踪,我可以将问题缩小为“401 未授权”错误。
这是我函数的重要部分:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls |
SecurityProtocolType.Tls12 |
SecurityProtocolType.Tls11;
foreach (var project in list.Take(1)) //fails if I try list.Take(2) or more
{
using (WebClient client = new WebClient
{
Credentials = CredentialCache.DefaultCredentials
})
{
UriBuilder address = new UriBuilder
{
Scheme = Request.Url.Scheme,
Host = Request.Url.Host,
Port = Request.Url.Port,
Path = "/ERP_ProjectPrint.aspx",
Query = string.Format("bpId={0}&bpVid={1}", project.Id, project.VersionId)
};
string fileName = project.VersionProtocol + ".html";
client.DownloadFile(address.Uri.ToString(), tempFilePath + fileName);
}
}
关于 IIS 设置的任何提示我可以调整以解决此问题?
尝试将循环移动到您的请求中,如下所示。这有什么区别吗?
也不认为你需要使用list.Take
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls |
SecurityProtocolType.Tls12 |
SecurityProtocolType.Tls11;
System.Net.ServicePointManager.DefaultConnectionLimit = 10
using (WebClient client = new WebClient
{
Credentials = CredentialCache.DefaultCredentials
})
{
foreach (var project in list)
{
UriBuilder address = new UriBuilder
{
Scheme = Request.Url.Scheme,
Host = Request.Url.Host,
Port = Request.Url.Port,
Path = "/ERP_ProjectPrint.aspx",
Query = string.Format("bpId={0}&bpVid={1}", project.Id, project.VersionId)
};
string fileName = project.VersionProtocol + ".html";
client.DownloadFileTaskAsync(address.Uri.ToString(), tempFilePath + fileName).Wait();
}
}
}
问题已通过在服务器上启用 TLS 1.2 得到解决:默认情况下未启用。参考https://tecadmin.net/enable-tls-on-windows-server-and-iis/.
请注意,启用它可能会破坏与服务器的 RDP 连接功能。
感谢 Jokies Ding 为我指明了正确的方向(见上面的评论)
在 using() 语句中 Dispose() 似乎无法正常工作:
using (WebClient client = new WebClient())
{ ... }
没有 using() 语句的解决方法:
WebClient client = new WebClient();
client.DownloadFileCompleted += OnDownloadFileCompleted;
下载完成时:
client.Dispose()
对我有用。
我构建了一个功能,可以从我的网站(.NET 网络表单、旧应用程序)下载一系列报告,将它们另存为临时文件夹中的 .html 文件,压缩它们并 return给用户的存档。 该应用程序使用 windows 身份验证,我通过启用
设法在请求中传递了当前用户凭据Credentials = CredentialCache.DefaultCredentials
一切都在我的开发环境中无缝运行(在 IIS Express 和 IIS 中),但在生产服务器(Windows 服务器 2008 R2,IIS 7.5)上,它仅在我将周期限制为一次迭代时才有效只要。 看起来 WebClient 底层连接保持打开状态,服务器拒绝在下一个周期打开另一个连接。 我收到的错误消息是
The request was aborted: Could not create SSL/TLS secure channel.
并且,启用 WCF 跟踪,我可以将问题缩小为“401 未授权”错误。
这是我函数的重要部分:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls |
SecurityProtocolType.Tls12 |
SecurityProtocolType.Tls11;
foreach (var project in list.Take(1)) //fails if I try list.Take(2) or more
{
using (WebClient client = new WebClient
{
Credentials = CredentialCache.DefaultCredentials
})
{
UriBuilder address = new UriBuilder
{
Scheme = Request.Url.Scheme,
Host = Request.Url.Host,
Port = Request.Url.Port,
Path = "/ERP_ProjectPrint.aspx",
Query = string.Format("bpId={0}&bpVid={1}", project.Id, project.VersionId)
};
string fileName = project.VersionProtocol + ".html";
client.DownloadFile(address.Uri.ToString(), tempFilePath + fileName);
}
}
关于 IIS 设置的任何提示我可以调整以解决此问题?
尝试将循环移动到您的请求中,如下所示。这有什么区别吗?
也不认为你需要使用list.Take
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls |
SecurityProtocolType.Tls12 |
SecurityProtocolType.Tls11;
System.Net.ServicePointManager.DefaultConnectionLimit = 10
using (WebClient client = new WebClient
{
Credentials = CredentialCache.DefaultCredentials
})
{
foreach (var project in list)
{
UriBuilder address = new UriBuilder
{
Scheme = Request.Url.Scheme,
Host = Request.Url.Host,
Port = Request.Url.Port,
Path = "/ERP_ProjectPrint.aspx",
Query = string.Format("bpId={0}&bpVid={1}", project.Id, project.VersionId)
};
string fileName = project.VersionProtocol + ".html";
client.DownloadFileTaskAsync(address.Uri.ToString(), tempFilePath + fileName).Wait();
}
}
}
问题已通过在服务器上启用 TLS 1.2 得到解决:默认情况下未启用。参考https://tecadmin.net/enable-tls-on-windows-server-and-iis/.
请注意,启用它可能会破坏与服务器的 RDP 连接功能。
感谢 Jokies Ding 为我指明了正确的方向(见上面的评论)
在 using() 语句中 Dispose() 似乎无法正常工作:
using (WebClient client = new WebClient())
{ ... }
没有 using() 语句的解决方法:
WebClient client = new WebClient();
client.DownloadFileCompleted += OnDownloadFileCompleted;
下载完成时:
client.Dispose()
对我有用。