WCF MessageContract无法绑定类:端点中MessageContract为空
WCF接收SOAP请求时MessageContract绑定空值问题解决
问题场景
需在WCF中接收固定格式的SOAP请求,要求以MessageContract作为输入(因返回类型也需用MessageContract),且无法修改请求格式,但当前代码始终获取到空值。
原始SOAP请求:
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"> <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"> <wsa:To>http://localhost/SomeService.svc</wsa:To> <wsa:MessageID soapenv:mustUnderstand="true">urn:uuid:72A256A3317AF1411C1719318536115</wsa:MessageID> <wsa:Action soapenv:mustUnderstand="true">urn:ihe:iti:2007:CrossGatewayQuery</wsa:Action> </soapenv:Header> <soapenv:Body> <query:AdhocQueryRequest xmlns:query="urn:oasis:names:tc:ebxml-regrep:xsd:query:3.0" xmlns:rs="urn:oasis:names:tc:ebxml-regrep:xsd:rs:3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0"> <query:ResponseOption returnComposedObjects="true" returnType="ObjectRef" /> <AdhocQuery id="urn:uuid:14d4debf-8f97-4251-9a74-a90016b0af0d" home="2.16.840.1.113883.3.9075"> <Slot name="$XDSDocumentEntryPatientId"> <ValueList> <Value>'111111111^^^&2.16.840.1.113883.4.1&ISO'</Value> </ValueList> </Slot> <Slot name="$XDSDocumentEntryStatus"> <ValueList> <Value>('urn:oasis:names:tc:ebxml-regrep:StatusType:Approved', 'urn:oasis:names:tc:ebxml-regrep:StatusType:Deprecated')</Value> </ValueList> </Slot> </AdhocQuery> </query:AdhocQueryRequest> </soapenv:Body> </soapenv:Envelope>
现有代码的核心错误
DQ_RequestMessage中MessageBodyMember的命名空间错误,AdhocQueryRequest属于query命名空间而非rim命名空间DQ_RequestBody中ResponseOption未匹配SOAP中的query前缀命名空间- 根元素的命名空间声明属性处理不符合XML规范
修正后的代码
MessageContract类
[MessageContract(IsWrapped = false)] public class DQ_RequestMessage { // 匹配SOAP中AdhocQueryRequest的query命名空间 [MessageBodyMember(Name = "AdhocQueryRequest", Namespace = "urn:oasis:names:tc:ebxml-regrep:xsd:query:3.0")] public DQ_RequestBody Body { get; set; } public DQ_RequestMessage() { } public DQ_RequestMessage(DQ_RequestBody body) { Body = body; } }
请求体类
// 指定根元素的默认命名空间为rim命名空间 [XmlRoot(Namespace = "urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0")] public class DQ_RequestBody { // 处理xmlns:xxx类型的命名空间声明,必须指定xmlns专属命名空间 [XmlAttribute(AttributeName = "query", Namespace = "http://www.w3.org/2000/xmlns/")] public string QueryNamespace { get; set; } [XmlAttribute(AttributeName = "rs", Namespace = "http://www.w3.org/2000/xmlns/")] public string RsNamespace { get; set; } [XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")] public string XsiNamespace { get; set; } // 匹配SOAP中query:ResponseOption的命名空间 [XmlElement(ElementName = "ResponseOption", Namespace = "urn:oasis:names:tc:ebxml-regrep:xsd:query:3.0")] public ResponseOption ResponseOption { get; set; } public class ResponseOption { [XmlAttribute(AttributeName = "returnComposedObjects")] public bool ReturnComposedObjects { get; set; } [XmlAttribute(AttributeName = "returnType")] public string ReturnType { get; set; } } // 继承根元素的默认rim命名空间,无需额外指定 [XmlElement(ElementName = "AdhocQuery")] public AdhocQuery AdhocQuery { get; set; } public class AdhocQuery { [XmlAttribute(AttributeName = "id")] public string Id { get; set; } [XmlAttribute(AttributeName = "home")] public string Home { get; set; } [XmlElement(ElementName = "Slot")] public List<Slot> Slots { get; set; } public AdhocQuery() { Slots = new List<Slot>(); } public class Slot { [XmlAttribute(AttributeName = "name")] public string Name { get; set; } [XmlElement(ElementName = "ValueList")] public ValueList ValueList { get; set; } public class ValueList { [XmlElement(ElementName = "Value")] public List<string> Values { get; set; } public ValueList() { Values = new List<string>(); } } } } }
关键修正说明
- 命名空间精准匹配:所有元素的命名空间必须与SOAP请求中的前缀/命名空间完全对应,这是WCF XML序列化的核心要求。
- 命名空间声明处理:xmlns:xxx属性属于
http://www.w3.org/2000/xmlns/专属命名空间,必须显式指定才能正确解析。 - 类型优化:将
returnComposedObjects改为bool类型,WCF会自动完成字符串到布尔值的转换,更符合业务逻辑。 - 集合初始化:给集合类型添加构造函数初始化,避免空引用问题。
内容的提问来源于stack exchange,提问作者Spencer Sullivan
相关产品推荐
相关产品推荐

