WCF XML 反序列化对命名空间和别名非常挑剔
WCF XML deserialization is being very picky about namespaces and aliases
我正在编写 .net WCF SOAP 服务,试图与 Java 客户端集成。这个过程有点不寻常,因为客户端指定了WSDL,我必须创建一个可以接受他们请求的服务。
当我们尝试执行集成时,我得到了一些非常挑剔的结果。非常细微的差异(在我看来似乎没问题)导致 XML 反序列化失败。
这是客户端实际生成的 XML,它最终为 CCHNameSearchResponse 的所有子属性提供了空值,例如 [=27] 中设置为“999”的 InterfaceControlField =]遇到空的)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:soapclient.cch.doj.state.wi.us">
<soapenv:Header/>
<soapenv:Body>
<impl:CCHNameSearchResponse xmlns:impl="urn:soapclient.cch.doj.state.wi.us" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<InterfaceControlField>999</InterfaceControlField>
这个有效,唯一的区别是名称空间别名 (xmlns:impl=) 在我看来可以接受吗?
xmlns:urn="urn:soapclient.cch.doj.state.wi.us">
<soapenv:Header/>
<soapenv:Body>
<CCHNameSearchResponse xmlns="urn:soapclient.cch.doj.state.wi.us" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<InterfaceControlField xmlns="">999</InterfaceControlField>
为什么?我怎样才能让它接受生成的 XML?
问题是如果没有别名,命名空间将成为所有子元素的默认命名空间。
使用别名,子元素位于 "no-namespace" 中,因此在序列化中无法正确拾取。
这是符合规范的,因此为我生成 XML 的一方存在问题。
http://www.w3.org/TR/xml-names/#defaulting
因此,要么不使用别名(根据 OP 中的第二个示例),要么必须在所有地方使用别名,如此处的示例
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:soapclient.cch.doj.state.wi.us">
<soapenv:Header/>
<soapenv:Body>
<impl:CCHNameSearchResponse xmlns:impl="urn:soapclient.cch.doj.state.wi.us" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<impl:InterfaceControlField>999</impl:InterfaceControlField>
我刚刚遇到了同样的问题,我通过向作为请求一部分的复杂类型添加和清空命名空间解决了这个问题。
ServiceContract(Namespace = "www.someDomainName.com")]
[XmlSerializerFormat]
public interface IExampleService
{
[OperationContract]
ServiceResponse TestCall(ServiceRequest request);
}
[MessageContract(WrapperNamespace = "www.someDomainName.com")]
public class ServiceRequest
{
[MessageBodyMember (Name="CallID",Namespace="")]
public CallID CallId { get; set; }
}
然后正确反序列化:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:namespaceAlias="www.someDomainName.com">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<namespaceAlias:ServiceRequest >
<CallID>
<TransactionUID>r4werf</TransactionUID>
<CallUID>fdsf</CallUID>
</CallID>
</namespaceAlias:ServiceRequest>
</s:Body>
</s:Envelope>
我正在编写 .net WCF SOAP 服务,试图与 Java 客户端集成。这个过程有点不寻常,因为客户端指定了WSDL,我必须创建一个可以接受他们请求的服务。
当我们尝试执行集成时,我得到了一些非常挑剔的结果。非常细微的差异(在我看来似乎没问题)导致 XML 反序列化失败。
这是客户端实际生成的 XML,它最终为 CCHNameSearchResponse 的所有子属性提供了空值,例如 [=27] 中设置为“999”的 InterfaceControlField =]遇到空的)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:soapclient.cch.doj.state.wi.us">
<soapenv:Header/>
<soapenv:Body>
<impl:CCHNameSearchResponse xmlns:impl="urn:soapclient.cch.doj.state.wi.us" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<InterfaceControlField>999</InterfaceControlField>
这个有效,唯一的区别是名称空间别名 (xmlns:impl=) 在我看来可以接受吗?
xmlns:urn="urn:soapclient.cch.doj.state.wi.us">
<soapenv:Header/>
<soapenv:Body>
<CCHNameSearchResponse xmlns="urn:soapclient.cch.doj.state.wi.us" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<InterfaceControlField xmlns="">999</InterfaceControlField>
为什么?我怎样才能让它接受生成的 XML?
问题是如果没有别名,命名空间将成为所有子元素的默认命名空间。
使用别名,子元素位于 "no-namespace" 中,因此在序列化中无法正确拾取。
这是符合规范的,因此为我生成 XML 的一方存在问题。
http://www.w3.org/TR/xml-names/#defaulting
因此,要么不使用别名(根据 OP 中的第二个示例),要么必须在所有地方使用别名,如此处的示例
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:soapclient.cch.doj.state.wi.us">
<soapenv:Header/>
<soapenv:Body>
<impl:CCHNameSearchResponse xmlns:impl="urn:soapclient.cch.doj.state.wi.us" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<impl:InterfaceControlField>999</impl:InterfaceControlField>
我刚刚遇到了同样的问题,我通过向作为请求一部分的复杂类型添加和清空命名空间解决了这个问题。
ServiceContract(Namespace = "www.someDomainName.com")]
[XmlSerializerFormat]
public interface IExampleService
{
[OperationContract]
ServiceResponse TestCall(ServiceRequest request);
}
[MessageContract(WrapperNamespace = "www.someDomainName.com")]
public class ServiceRequest
{
[MessageBodyMember (Name="CallID",Namespace="")]
public CallID CallId { get; set; }
}
然后正确反序列化:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:namespaceAlias="www.someDomainName.com">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<namespaceAlias:ServiceRequest >
<CallID>
<TransactionUID>r4werf</TransactionUID>
<CallUID>fdsf</CallUID>
</CallID>
</namespaceAlias:ServiceRequest>
</s:Body>
</s:Envelope>