在 SOAP 请求 .NET CORE 2.2 上发送的 Http.WinHttpException。收到的消息是意外的或格式错误
Posted
技术标签:
【中文标题】在 SOAP 请求 .NET CORE 2.2 上发送的 Http.WinHttpException。收到的消息是意外的或格式错误【英文标题】:Http.WinHttpException sent on SOAP request .NET CORE 2.2. The message received was unexpected or badly formatted 【发布时间】:2021-11-28 23:06:30 【问题描述】:我们的 .NETCore2.0 webapp 中有三个 IHostedService 定期执行操作。其中两个正在轮询外部系统以获取新数据;第三个将我们的 webapp 收集的一些数据发送到同一个外部系统。每个请求都是 SOAP,并使用以下代码完成:
try
#region PFC Certificate
// Pfx certificate management
string certPath = GetCertPath();
string certPass = GetCertPassword();
X509Certificate2Collection X509collection = new X509Certificate2Collection();
X509collection.Import(certPath, certPass, X509KeyStorageFlags.PersistKeySet);
#endregion
if (X509collection.Count > 0)
X509Certificate2 x509 = X509collection[0];
var request = CreateSOAPWebRequest(url, x509);
byte[] bytes;
bytes = Encoding.ASCII.GetBytes(xmlRequestContent);
request.ContentType = "application/xml; encoding='utf-8'";
request.ContentLength = bytes.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close();
if (request == null) throw new Exception($"url:url: Request NULL - xml: xmlRequestContent");
try
using (HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync())
if (response.StatusCode == HttpStatusCode.OK)
using (Stream responseStream = response.GetResponseStream())
// Response deserialization
string responseStr = await new StreamReader(responseStream).ReadToEndAsync();
T result = new T();
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (StringReader reader = new StringReader(responseStr))
result = (T)(serializer.Deserialize(reader));
return result;
catch (WebException ex)
_logger.LogError(ex);
throw;
return default(T);
catch(Exception ex)
_logger.LogError(ex);
throw;
CreateSOAPWebRequest 方法定义为:
private HttpWebRequest CreateSOAPWebRequest(string url, X509Certificate certificate)
Uri uri = new Uri(url);
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
webRequest.Proxy = null;
webRequest.Headers.Add("SOAP:Action");
webRequest.KeepAlive = true;
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
webRequest.AuthenticationLevel = AuthenticationLevel.MutualAuthRequired;
if (certificate != null)
webRequest.ClientCertificates.Add(certificate);
return webRequest;
自从第三个服务出现以来,前两个托管服务多年来一直很好地协同工作:一些请求在开始时正常,然后抛出这个异常,并且没有一个服务能够再发送 SOAP 请求(直到我们重启webapp):
The SSL connection could not be established, see inner exception. Authentication failed, see inner exception.
---> The SSL connection could not be established, see inner exception.
---> Authentication failed, see inner exception.
---> The message received was unexpected or badly formatted
这个扔就行了
HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync()
这似乎是证书/安全/SSL 问题。但是请求在一开始和/或没有第三个托管服务时运行良好,所以我们认为这可能是服务之间的同步问题,我们通过单独在一个单独的克隆 web 应用程序上运行它来分离第三个,但我们得到了无论如何,在第二个 SOAP 调用上出现同样的错误(虽然第一个有效)。
我们只能通过在生产环境中禁用服务并在本地以调试模式运行 webapp、读取和发送生产数据来在调试中重现此错误。
我们不知道是什么原因造成的,所以提前感谢您的每一个建议。
【问题讨论】:
【参考方案1】:我终于明白了。当异常说实话时,整个事情有点误导:在我们的代码中的某个时刻,在 SOAP 请求之后,流程可能会经历这样的事情:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
所以在这条指令之前一切都很好,当然在这条指令之后一切都坏了。
【讨论】:
以上是关于在 SOAP 请求 .NET CORE 2.2 上发送的 Http.WinHttpException。收到的消息是意外的或格式错误的主要内容,如果未能解决你的问题,请参考以下文章
从 C# .NET Core(特别是 Workday)调用 Java Web 服务。如何在soap请求中获取xml属性
从 .NET Core 2.2 迁移到 3.1 后,EF Core 随机抓取 API 请求上的用户表
尝试使用 net core / net 5 连接 SOAP 服务
将项目从 2.2 更新到 3.1(缺少程序集)或如何在 .NET Core 中使用 API POST 请求时,PostAsJsonAsync()在 .Net Core 3.1 中不起作用 [重复]