https请求仅在.net Web应用程序中失败

use*_*705 5 .net c# ups http xmlhttprequest

我正在尝试修补.net Web应用程序,该应用程序经过多年的工作开始未能获得UPS的运送报价,这对Web业务产生了巨大影响。经过反复试验和错误,我发现以下代码在控制台应用程序中可以正常运行:

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";
}
Run Code Online (Sandbox Code Playgroud)

这可以在Visual Studio中很好地运行,并且可以从UPS那里得到一个很小的响应,即XML当然是错误的。

但是,如果我将此函数粘贴到Web应用程序中而不更改单个字符,则会抛出异常request.GetRequestStream()

身份验证失败,因为远程方已关闭传输流。

我在应用程序中的几个不同位置尝试了相同的结果。

Web应用程序环境会影响请求什么?

use*_*705 5

事实证明这是TLS问题。我猜控制台应用程序默认使用比Web应用程序更高的协议,尽管未指定。因此,您所要做的就是在发出请求之前的某个时间添加以下代码行:

using System.Net;
...
System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
Run Code Online (Sandbox Code Playgroud)

尽管我花了很多钱去那儿,但这就是全部。

这是UPS关于此问题的回复:

自2018年1月18日起生效,UPS将仅接受TLS 1.1和TLS 1.2安全协议...使用生产URL(onlinetools.ups.com/tool name)时使用TLS 1.0的客户的100%请求将被拒绝。

无论如何,希望这对某人有帮助。

吉姆