.NET Core Web API接收SOAP请求时自定义Request对象始终为null的问题排查
看起来你遇到的核心问题是XML序列化与数据契约定义不匹配,导致请求无法正确映射到你的Request对象上。我帮你梳理几个关键的修复点:
1. 给Request类补上[DataContract]特性
你目前只给Child1加了[DataContract],但Request类没有这个标记。DataContractSerializer(或配合SOAP的序列化器)需要这个特性来识别整个请求对象的结构,否则无法正确解析XML内容。修改后的Request类应该是这样:
[DataContract] public class Request { [DataMember] public Child1 child1 { get; set; } [DataMember(Name = "child2")] public string child2 { get; set; } }
2. 修复Child1中带点的属性名问题
XML标签是<child1.1>,但C#属性名不允许包含.,你需要用[DataMember(Name = "child1.1")]来显式映射XML标签名,替换掉非法的属性名:
[DataContract] public class Child1 { // 用合法的C#属性名,通过Name属性关联XML的<child1.1>标签 [DataMember(Name = "child1.1")] public string Child1_1 { get; set; } }
3. 对齐序列化器配置
你在端点配置中用了SoapSerializer.XmlSerializer,但DataContract特性是和DataContractSerializer配套使用的。这里有两种选择:
选项A:改用DataContractSerializer
把端点配置改成使用DataContractSerializer,这样和你的DataContract定义匹配:
app.UseSoapEndpoint<ISampleService>("/Service.svc", new BasicHttpBinding(), SoapSerializer.DataContractSerializer);
选项B:改用XmlSerializer的特性(推荐如果更贴合原有XML结构)
如果你想继续用XmlSerializer,可以把类定义换成XmlSerializer的特性(比如[XmlRoot]、[XmlElement]),这样更直接:
[XmlRoot("root")] public class Request { [XmlElement("child1")] public Child1 Child1 { get; set; } [XmlElement("child2")] public string Child2 { get; set; } } public class Child1 { [XmlElement("child1.1")] public string Child1_1 { get; set; } }
这种情况下保持原来的SoapSerializer.XmlSerializer配置即可。
4. 验证Postman的SOAP请求结构
最后要确保你发送的SOAP请求结构正确,尤其是命名空间和标签嵌套要和你的契约匹配。举个符合要求的请求示例(注意替换成你服务的命名空间):
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:svc="http://your-service-namespace"> <soapenv:Header/> <soapenv:Body> <svc:Root> <svc:child1> <svc:child1.1>192.168.1.1</svc:child1.1> </svc:child1> <svc:child2>true</svc:child2> </svc:Root> </soapenv:Body> </soapenv:Envelope>
按照这几个步骤调整后,应该就能正确将XML请求映射到你的Request对象了。
内容的提问来源于stack exchange,提问作者Angelus

