c# - wcf 客户端在反序列化期间忽略派生类型

标签 c# wcf soap wsdl deserialization

我正在使用标准 wsdl(位于 here)与服务 (OpenXDS) 通信。我从中创建了一个服务引用,它生成了一个非常大的 Reference.cs 文件。文件中有这样的类型层次结构:

public partial class ExtrinsicObjectType : RegistryObjectType

. . .

[System.Xml.Serialization.XmlIncludeAttribute(typeof(ExtrinsicObjectType))]
public partial class RegistryObjectType : IdentifiableType

. . .

[System.Xml.Serialization.XmlIncludeAttribute(typeof(RegistryObjectType))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(ExtrinsicObjectType))]
public partial class IdentifiableType : object

所有三种类型都具有相同的 XmlType:

[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0")]

Response类型中有一个IdentifiableType对象的集合:

[System.Xml.Serialization.XmlArrayAttribute(Namespace="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0", Order=0)]
[System.Xml.Serialization.XmlArrayItemAttribute("Identifiable", IsNullable=false)]
public IdentifiableType[] RegistryObjectList { 

当服务实际响应时,它会给出一个 ExtrinsicObject 元素的集合:

<rim:RegistryObjectList xmlns:rim="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0">
  <ns1:ExtrinsicObject xmlns:ns1="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0" ...
  <ns1:ExtrinsicObject xmlns:ns1="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0" ...
  <ns1:ExtrinsicObject xmlns:ns1="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0" ...
  <ns1:ExtrinsicObject xmlns:ns1="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0" ...
  <ns1:ExtrinsicObject xmlns:ns1="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0" ...
</rim:RegistryObjectList>

我在跟踪日志中看到了这些元素,并且我可以在 SoapUI 中得到相同的答案。但是当我从客户端代理得到反序列化的响应时,RegistryObjectList 是空的。它完全忽略了 ExtrinsicObject 元素。

我改不了服务器,客户端是VS2012生成的。看起来这应该可以正常工作,我缺少一些设置或其他东西。

这是我目前的理论:

  • 服务引用上有一些设置,如果我检查它并更新代码,一切都会正常工作。
  • 我使用的 wsdl 与他们同意的 wsdl 不同。
  • 我将不得不弄清楚如何手动反序列化响应。

感谢任何帮助。我已尝试包括我认为相关的内容,但由于 wsdl、xsd 和 Reference.cs 都相当大,因此需要进行大量编辑。

最佳答案

我只是通过传递以下 XmlAttributeOverrides 来让这个工作正常进行到序列化器:

var overrides = new XmlAttributeOverrides();
overrides.Add(typeof(SubmitObjectsRequest), "RegistryObjectList", new XmlAttributes
{
    XmlArray = new XmlArrayAttribute()
    {
        Namespace = "urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0",
        Order = 0
    },
    XmlArrayItems =
    {
        new XmlArrayItemAttribute("ExtrinsicObject", typeof(ExtrinsicObjectType)) { IsNullable = false },
        new XmlArrayItemAttribute("RegistryPackage", typeof(RegistryPackageType)) { IsNullable = false }
    }
});

据我了解,如您所说,Reference.cs 给出了以下内容:

[System.Xml.Serialization.XmlArrayAttribute(Namespace="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0", Order=0)]
[System.Xml.Serialization.XmlArrayItemAttribute("Identifiable", IsNullable=false)]
public IdentifiableType[] RegistryObjectList {

但由于在 XML 中,RegistryObjectList 元素没有 Identifiable 子节点,而是 ExtrinsicObjectRegistryPackage children ,我真正想要的是它看起来像这样:

[System.Xml.Serialization.XmlArrayAttribute(Namespace="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0", Order=0)]
[System.Xml.Serialization.XmlArrayItemAttribute("ExtrinsicObject", typeof(ExtrinsicObjectType), IsNullable=false)]
[System.Xml.Serialization.XmlArrayItemAttribute("RegistryPackage", typeof(RegistryPackageType), IsNullable=false)]
public IdentifiableType[] RegistryObjectList {

并且包含覆盖使得序列化程序忽略原始属性并将 RegistryObjectList 视为已被后者装饰。

关于c# - wcf 客户端在反序列化期间忽略派生类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18618920/

相关文章:

c# - 将 RabbitMQ 与 nServiceBus(用于 C#)结合使用与使用 Amazon SQS

c# - 使用 int 而不是\uNN 将 Unicode 代码点打印到控制台

c# - WCF 客户端在外部解决方案时不工作

wcf - 从 WCF RESTful web 服务读取 cookie

wcf - 使 WCF 服务可通过 Internet 访问

java - Apache CXF,从 WSDL 文件生成 Web 服务

c# - WhenAny vs WhenAll vs WaitAll vs none,考虑到结果正在被立即使用

c# - 使用双缓冲技术进行并发读写?

java - 如何将没有前缀的childElements添加到Soap header ?

python - 带有 Zeep 和 Python 的 SOAP 客户端中的 Bearer Token 授权 header