【问题标题】:Xml deserialization not binding listxml反序列化不绑定列表
【发布时间】:2018-09-03 10:53:08
【问题描述】:

我有一个如下所示的 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
}

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

而且我不确定&lt;d3p1:KeyValuePairOfStringDatagxNgnmsk&gt; 末尾的“gxNgnmsk”是否意味着什么……响应背后的人不知道它是什么。

【问题讨论】:

  • 参见:stackoverflow.com/questions/2911514/… 使用 XML Linq 很容易做到。
  • @Icepickle 那个小写字母是我在网站上的一个错字
  • 您能否edit 分享包含Data 的一些值的示例XML?这将指示 Data 本身元素的名称空间。 "http://schemas.datacontract.org/2004/07/System.Collections.Generic" 几乎可以肯定是 Data 的错误命名空间,但没有足够的信息来确定正确的命名空间应该是什么。

标签: c# xml datacontractserializer xml-deserialization


【解决方案1】:

&lt;d3p1:KeyValuePairOfStringDatagxNgnmsk&gt; 末尾的“gxNgnmsk”是您的问题的原因。 Data Contract Names for Generic Types中解释了这个后缀的存在:

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

默认情况下,泛型类型的数据协定名称是该类型的名称,后跟字符串“Of”,然后是泛型参数的数据协定名称,后跟 散列 使用泛型参数的数据协定命名空间计算。 ...当所有泛型参数都是原始类型时,哈希被省略。

"gxNgnmsk" 是哈希值。如果我使用你的类从内存中创建的实例生成 XML,我会得到一个不同的哈希:

<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>

显然您的Data 类型没有正确的数据协定namespace,导致生成不一致的哈希。 (而且,从实验来看,"http://schemas.datacontract.org/2004/07/System.Collections.Generic""http://schemas.datacontract.org/2004/07/a""" 似乎都没有生成正确的哈希值。可能我可以从完整的 XML 示例中猜出正确的命名空间,但提供的简化 XML 中没有足够的信息。)

那么,有什么办法可以解决这个问题呢?

  1. 您可以让“响应背后的人”告诉您所有合约类型(包括 Data)的正确数据合约名称和命名空间。无论如何,这对于data contract equivalence 在通过网络发送数据时是必需的,因此他们应该能够提供此信息。

  2. 如果“响应背后的人”提供 WSDL(他们应该),您应该能够auto-generate a client,这应该可以正常工作。

  3. 但在没有上述情况的情况下,您可以通过使用自定义 collection data contract 创建一个集合来解决该问题:

    [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,可以在不知道Data 的正确命名空间的情况下反序列化示例XML。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多