我正在尝试修补一个 .net 网络应用程序,该应用程序在多年工作后开始无法获得 UPS 运输报价,这极大地影响了网络业务。经过反复试验,我发现以下代码在控制台应用程序中运行良好:
static string FindUPSPlease()
{
string post_data = "<xml data string>";
string uri = "https://onlinetools.ups.com/ups.app/xml/Rate";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
byte[] postBytes = Encoding.ASCII.GetBytes(post_data);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postBytes.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
// get response and send to console
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Console.WriteLine(new StreamReader(response.GetResponseStream()).ReadToEnd());
Console.WriteLine(response.StatusCode);
return "done";
}
这在 Visual Studio 中运行得很好,并且从 UPS 得到了一个很好的小响应,即 XML 当然是格式错误的。
但是,如果我在不更改单个字符的情况下将此函数粘贴到 Web 应用程序中,则会在 request.GetRequestStream()
上引发异常:
Authentication failed because the remote party has closed the transport stream.
我在应用程序的几个不同位置尝试过,结果相同。
会影响请求的 Web 应用程序环境有哪些?
最佳答案
事实证明是 TLS 问题。我猜控制台应用程序默认使用比 Web 应用程序更高的协议(protocol),尽管没有指定。因此,您所要做的就是在发出请求之前的某个时间添加以下代码行:
using System.Net;
...
System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
这就是它所需要的全部,尽管我花了很多时间才到达那里。
这是 UPS 对这个问题的回应:
Effective January 18, 2018, UPS will only accept TLS 1.1 and TLS 1.2 security protocols... 100% of requests from customers who are on TLS 1.0 while using production URLS (onlinetools.ups.com/tool name) will be rejected.
无论如何,希望这对某人有所帮助。
吉姆
关于c# - https 请求仅在 .net web 应用程序中失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48969650/