You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core迁移至.NET 6:HttpClient替代WebRequest的SOAP请求改造问题

正确使用HttpClient改造SOAP请求代码

首先,你的改造思路方向是对的,但需要调整整体流程——因为HttpClient的设计和WebRequest完全不同,不能直接替换返回类型,需要重构整个请求处理逻辑。以下是完整的改造方案:

核心改造要点

  • 复用HttpClient实例:不要每次请求都创建新的HttpClient,否则会导致套接字耗尽问题,建议使用静态实例。
  • 直接构建请求内容:HttpClient不需要先创建空请求再写入流,而是直接从SOAP消息字符串构建请求内容。
  • 异步优先:HttpClient的方法都是异步的,推荐使用异步模式(若需要同步版本可基于异步方法封装)。
  • 匹配原请求头:确保ContentType、SOAPAction、Accept等请求头和原代码完全一致。

完整改造代码

// 静态HttpClient实例,全局复用
private static readonly HttpClient _httpClient = new HttpClient();

/// <summary>
/// 异步发送SOAP请求(推荐使用)
/// </summary>
private static async Task<string> PostSoapAsync(string url, string soapMessage, string action)
{
    // 构建请求内容:使用不带BOM的UTF8编码,匹配原XmlDocument.Save的行为
    var content = new StringContent(soapMessage, new UTF8Encoding(false));
    
    // 设置ContentType头,和原代码完全一致(包含引号)
    content.Headers.ContentType = MediaTypeHeaderValue.Parse("text/xml;charset=\"utf-8\"");
    
    // 添加SOAPAction头,保留原有的引号格式
    content.Headers.Add("SOAPAction", $"\"{action}\"");
    
    // 创建HttpRequestMessage,设置Accept头
    var request = new HttpRequestMessage(HttpMethod.Post, url)
    {
        Content = content
    };
    request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));

    try
    {
        // 发送请求并获取响应
        using var response = await _httpClient.SendAsync(request);
        // 检查请求是否成功,失败则抛出异常(后续捕获处理)
        response.EnsureSuccessStatusCode();
        // 读取响应内容
        return await response.Content.ReadAsStringAsync();
    }
    catch (HttpRequestException ex)
    {
        // 处理错误响应,和原代码逻辑一致
        if (ex.Response != null)
        {
            return await ex.Response.Content.ReadAsStringAsync();
        }
        throw;
    }
}

/// <summary>
/// 同步发送SOAP请求(基于异步方法封装,仅适用于非UI线程场景)
/// </summary>
private static string PostSoap(string url, string soapMessage, string action)
{
    return PostSoapAsync(url, soapMessage, action).GetAwaiter().GetResult();
}

代码说明

  • 静态HttpClient:_httpClient是静态只读实例,全局复用,避免频繁创建销毁导致的性能问题。
  • StringContent构建:直接从SOAP消息字符串创建内容,使用UTF8Encoding(false)确保输出不带BOM,和原代码中XmlDocument.Save的行为一致。
  • 请求头设置:严格匹配原代码的ContentType(包含引号)和SOAPAction格式(带引号),避免服务器解析错误。
  • 错误处理:捕获HttpRequestException并读取错误响应内容,和原代码的WebException处理逻辑对齐。
  • 异步/同步版本:提供异步优先的PostSoapAsync,同时封装了同步版本(注意:同步版本在UI线程可能导致死锁,建议优先使用异步)。

替换原有调用

原来的PostSoap方法可以直接替换为新的方法,不需要再调用CreateSoapRequest、AddMessageToRequest和GetResponse——这些方法的逻辑已经整合到新的PostSoapAsync/PostSoap中。

内容的提问来源于stack exchange,提问作者Pratex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 22:20:38