.NET Core API接收SOAP XML报文参数为空/默认值问题咨询
根因说明
这个问题的核心是.NET 内置的XML序列化器默认要求请求XML的节点顺序必须和服务端实体类的属性序列化顺序完全匹配,默认序列化规则会自动按实体类属性的字母顺序生成预期的节点序列,只要请求XML节点顺序和预期顺序不符,未匹配到对应位置的属性就会被赋值为null或默认值,这就是你把XML节点调整为字母顺序后就能正常解析的原因。
解决方案
1. 显式指定属性序列化顺序(最稳妥,推荐)
根据客户端发送的XML实际节点顺序,给实体类的每个属性加上对应的序列化特性指定顺序即可,不用调整XML报文结构:
- 如果你当前用的是
XmlDataContractSerializer(对应AddXmlDataContractSerializerFormatters配置):
// 类头加DataContract特性 [DataContract] public class SoapRequestModel { // 按客户端节点顺序从小到大指定Order值 [DataMember(Order = 1)] public string FirstNode { get; set; } [DataMember(Order = 2)] public int SecondNode { get; set; } // 列表属性同样指定顺序即可 [DataMember(Order = 3)] public List<ItemType> ItemList { get; set; } }
- 如果你用
XmlSerializer:
public class SoapRequestModel { [XmlElement(Order = 1)] public string FirstNode { get; set; } [XmlElement(Order = 2)] public int SecondNode { get; set; } // 列表可以额外指定节点名避免匹配错误 [XmlArray("ItemList", Order =3), XmlArrayItem("Item")] public List<ItemType> ItemList { get; set; } }
2. 修复AddXmlSerializerFormatters无法正常收发XML的问题
你用这个配置无法发报文是因为默认的XML格式化器没有兼容SOAP协议的媒体类型,手动添加支持即可:
services.AddControllers() .AddXmlSerializerFormatters(options => { // 忽略未知的节点/属性,避免匹配多余节点时报错 options.SerializerOptions.UnknownAttributeHandling = UnknownAttributeHandling.Ignore; options.SerializerOptions.UnknownElementHandling = UnknownElementHandling.Ignore; }) .AddMvcOptions(options => { // 给输入格式化器添加SOAP常用媒体类型支持 var xmlInputFormatter = options.InputFormatters.OfType<XmlSerializerInputFormatter>().First(); xmlInputFormatter.SupportedMediaTypes.Add("text/xml"); xmlInputFormatter.SupportedMediaTypes.Add("application/soap+xml"); // 给输出格式化器添加SOAP常用媒体类型支持 var xmlOutputFormatter = options.OutputFormatters.OfType<XmlSerializerOutputFormatter>().First(); xmlOutputFormatter.SupportedMediaTypes.Add("text/xml"); xmlOutputFormatter.SupportedMediaTypes.Add("application/soap+xml"); });
3. 列表属性为null的额外检查
如果配置顺序后列表仍然为null,检查两个配置点:
- 列表特性指定的节点名称和客户端XML的列表节点、子节点名称完全一致,注意大小写
- 列表属性的访问修饰符必须是
public,没有加[XmlIgnore]之类的忽略序列化特性
内容的提问来源于stack exchange,提问作者Gert Dunon
相关产品推荐
相关产品推荐

