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

如何在.NET Core 6中接收SOAP请求?迁移遇XML解析错误

.NET Core 6 迁移SOAP服务解决XML解析错误方案

错误原因

当前代码的核心问题:使用[FromBody] string value接收SOAP请求,但通过AddXmlSerializerFormatters()配置的XML格式化器会尝试将application/soap+xml格式的请求反序列化为.NET对象,而非直接读取为字符串,导致XML解析逻辑与预期不符,抛出序列化错误。

解决方案

提供两种可行方案,可根据迁移需求选择:

方案1:直接读取原始SOAP请求内容

跳过XML格式化器,直接从请求流中读取完整的SOAP XML字符串,适合快速兼容旧代码逻辑:

修改控制器端点代码:

[ApiController]
public class DMVController : ControllerBase
{
    private readonly IProcess _process;

    public DMVController(IProcess process)
    {
        _process = process;
    }

    [Consumes("application/soap+xml")]
    [Produces("application/soap+xml")]
    [HttpPost, Route("/VerifyInsurance")]
    public async Task<IActionResult> Post()
    {
        // 读取原始请求内容
        string soapRequest;
        using (var reader = new StreamReader(Request.Body))
        {
            soapRequest = await reader.ReadToEndAsync();
        }

        // 调用原有处理逻辑
        var soapResponse = _process.ProcessRequest(soapRequest);
        
        // 返回SOAP响应,指定正确的Content-Type
        return Content(soapResponse, "application/soap+xml; charset=utf-8");
    }
}

方案2:强类型反序列化SOAP请求

定义与SOAP结构匹配的实体类,让XML格式化器自动完成反序列化,更符合.NET Core Web API规范:

步骤1:定义SOAP相关实体类

注意命名空间必须与请求中的XML命名空间完全一致:

[XmlRoot(ElementName = "Envelope", Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public class Soap12Envelope
{
    [XmlElement(ElementName = "Body", Namespace = "http://www.w3.org/2003/05/soap-envelope")]
    public SoapBody Body { get; set; }
}

public class SoapBody
{
    [XmlElement(ElementName = "CoverageRequest", Namespace = "http://www.iicmva.com/CoverageVerification/")]
    public CoverageRequest CoverageRequest { get; set; }
}

[XmlRoot(ElementName = "CoverageRequest", Namespace = "http://www.iicmva.com/CoverageVerification/")]
public class CoverageRequest
{
    [XmlElement(ElementName = "RequestorInformation")]
    public RequestorInformation RequestorInformation { get; set; }
    
    [XmlElement(ElementName = "Detail")]
    public Detail Detail { get; set; }
}

// 根据实际业务需求补充RequestorInformation和Detail的属性
public class RequestorInformation { }
public class Detail { }

步骤2:修改控制器端点

[ApiController]
public class DMVController : ControllerBase
{
    private readonly IProcess _process;

    public DMVController(IProcess process)
    {
        _process = process;
    }

    [Consumes("application/soap+xml")]
    [Produces("application/soap+xml")]
    [HttpPost, Route("/VerifyInsurance")]
    public IActionResult Post([FromBody] Soap12Envelope soapEnvelope)
    {
        if (soapEnvelope?.Body?.CoverageRequest == null)
        {
            return BadRequest("无效的SOAP请求格式");
        }

        // 基于强类型对象处理请求,生成响应信封
        var responseEnvelope = _process.ProcessRequest(soapEnvelope);
        
        return Ok(responseEnvelope);
    }
}

步骤3:优化XML格式化配置(可选)

如果需要支持更复杂的SOAP结构,可同时添加DataContract序列化支持:

// 在program.cs中修改控制器配置
builder.Services.AddControllers()
    .AddXmlSerializerFormatters()
    .AddXmlDataContractSerializerFormatters();

关键注意点

  • 方案2中,实体类的命名空间必须与请求XML中的命名空间严格匹配,这是反序列化成功的核心前提。
  • 返回SOAP响应时,务必指定Content-Type为application/soap+xml; charset=utf-8,确保客户端能正确解析响应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 17:43:12