XML反序列化不绑定列表

时间:2018-09-03 10:53:09

标签: c# xml datacontractserializer xml-deserialization

我有一个如下所示的XML文件:

<Stamdata xmlns="http://schemas.datacontract.org/2004/07/a">
  <Liste xmlns:d3p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
    <d3p1:KeyValuePairOfStringDatagxNgnmsk>
      <d3p1:key>key value</d3p1:key>
      <d3p1:value>
        ......
      </d3p1:value>
    </d3p1:KeyValuePairOfStringDatagxNgnmsk>
  </Liste>
</Stamdata>

我的任何模型看起来都是

[DataContract(Name = "Stamdata", Namespace = "http://schemas.datacontract.org/2004/07/a")]
public class Stamdata
{
   [DataMember]
   public KeyValuePair<string, Data>[] Liste { get; set; }
}

[DataContract(Name = "Data", Namespace = "http://schemas.datacontract.org/2004/07/System.Collections.Generic")]
public class Data
{
   //.... Many properties
}

我的问题是,即使该xml包含大约100个元素,该列表仍包含0个元素。

我不确定<d3p1:KeyValuePairOfStringDatagxNgnmsk>末尾的“ gxNgnmsk”是什么意思……响应背后的那个人不知道它是什么。

1 个答案:

答案 0 :(得分:0)

master末尾的“ gxNgnmsk”是导致问题的原因。此后缀的存在在Data Contract Names for Generic Types中进行了解释:

  

存在用于确定泛型类型的数据协定名称的特殊规则...

     

默认情况下,泛型类型的数据协定名称是该类型的名称,后跟字符串“ Of”,然后是泛型参数的数据协定名称,后跟一个哈希使用通用参数的数据协定名称空间进行计算。 ... ...当所有通用参数均为原始类型时,将省略哈希。

<d3p1:KeyValuePairOfStringDatagxNgnmsk>是哈希。而且,如果我使用您的类从内存中创建的实例生成XML,则会得到不同的哈希值:

"gxNgnmsk"

显然,您的<Stamdata xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/a"> <Liste xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic"> <d2p1:KeyValuePairOfstringDatatwCi8m_S7> <d2p1:key>key value</d2p1:key> <d2p1:value /> </d2p1:KeyValuePairOfstringDatatwCi8m_S7> </Liste> </Stamdata> 类型没有正确的数据协定namespace,导致生成了不一致的哈希。 (而且,根据实验,Data"http://schemas.datacontract.org/2004/07/System.Collections.Generic""http://schemas.datacontract.org/2004/07/a"似乎都不会生成正确的哈希值。可能我可以从完整的XML示例中猜出正确的名称空间,但是其中没有足够的信息提供的简化XML。)

那么,如何解决这个问题?

  1. 您可以得到“响应背后的一个”,以告诉您正确的数据合同名称和名称空间,适用于所有合同类型,包括""。无论如何,data contract equivalence在通过网络发送数据时都是必需的,因此他们应该能够提供此信息。

  2. 如果“响应背后的人”提供了WSDL(他们应该这样做),那么您应该可以auto-generate a client进行工作。

  3. 但是在没有上述情况的情况下,您可以通过使用自定义collection data contract创建一个包含哈希值散列的集合来解决此问题:

    Data

    使用此版本的[DataContract(Name = "Stamdata", Namespace = "http://schemas.datacontract.org/2004/07/a")] public class Stamdata { [DataMember] public DataList Liste { get; set; } } [CollectionDataContract( Namespace = "http://schemas.datacontract.org/2004/07/System.Collections.Generic", ItemName = "KeyValuePairOfStringDatagxNgnmsk")] public class DataList : List<KeyValuePair<string, Data>> { public DataList() : base() { } public DataList(IEnumerable<KeyValuePair<string, Data>> list) : base(list) { } } ,可以在不知道Stamdata正确的名称空间的情况下反序列化示例XML。