如何在.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
相关产品推荐
相关产品推荐

