C# REST API无法解析带soapenv前缀的SOAP Envelope XML请求
问题描述
我正在尝试创建一个接收XML而非JSON的基础REST API,控制器代码如下:
using Microsoft.AspNetCore.Mvc; using OEMTestFactoryREST.Models; [ApiController] [Route("[controller]")] public class VplController : ControllerBase { [HttpPost] [Consumes("application/xml")] public IActionResult CreateOrder([FromBody] Envelope envelope) { if (envelope == null) { return BadRequest("Invalid data"); } return Ok(); } }
Envelope.cs文件代码如下:
[XmlType(Namespace = "http://schemas.xmlsoap.org/soap/envelope/")] [XmlRoot(ElementName = "Envelope")] public class Envelope { }
为简化示例我移除了内部属性。通过Swagger发送不带命名空间前缀的XML请求:
<Envelope> </Envelope>
时一切正常,但发送客户端预期的带soapenv前缀且声明SOAP命名空间的XML请求:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> </soapenv:Envelope>
时,出现如下错误:
{ "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1", "title": "One or more validation errors occurred.", "status": 400, "traceId": "00-746f6559b87bd381a4f1ca98634d554b-e19eac5521a35ffe-00", "errors": { "": [ "An error occurred while deserializing input data." ], "orderblabla": [ "The orderblabla field is required." ] } }
问题出在开头的soapenv前缀,请问如何修改控制器或模型,使其支持带soapenv前缀的XML请求?
解决方案
1. 修正Envelope模型的命名空间配置
当前Envelope类的XmlRoot属性未指定命名空间,导致XML序列化器无法识别带SOAP命名空间的根元素(前缀soapenv只是命名空间的别名,核心是命名空间值)。修改XmlRoot属性,添加与XmlType一致的命名空间:
[XmlType(Namespace = "http://schemas.xmlsoap.org/soap/envelope/")] [XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")] public class Envelope { }
2. 确保项目配置了XML序列化支持
ASP.NET Core默认仅启用JSON序列化,需显式添加XML格式支持。在Program.cs中修改服务配置:
var builder = WebApplication.CreateBuilder(args); // 添加控制器并启用XML序列化器格式 builder.Services.AddControllers() .AddXmlSerializerFormatters(); // 使用XmlSerializer(对应模型的Xml*特性) // 若使用DataContractSerializer,可替换为AddXmlDataContractSerializerFormatters() var app = builder.Build(); app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
原理说明
XML的前缀(如soapenv)只是命名空间的简写,序列化器匹配的是元素的命名空间值而非前缀。给XmlRoot指定正确的命名空间后,无论请求中使用什么前缀,只要命名空间与模型配置一致,就能正确反序列化Envelope对象。
完成上述修改后,发送带soapenv前缀的XML请求即可正常被API接收处理。
内容的提问来源于stack exchange,提问作者user5861823
相关产品推荐
相关产品推荐

