【问题标题】:Deserializing xml Dictionary<TKey,TValue> with DataContactSerializer使用 DataContactSerializer 反序列化 xml Dictionary<TKey,TValue>
【发布时间】:2014-09-03 20:32:34
【问题描述】:

我正在尝试使用 DataContractSerializer 反序列化 Dictionary&lt;TKey,TValue&gt;。我没有例外,我的字典回来了null。我已经阅读了多篇文章,尝试了多种实现,但仍然没有成功。我敢肯定,我错过了一些非常小的东西,并且真的可以用几双眼睛为我查看它,也许将它分开并告诉我我的问题出在哪里。任何帮助是极大的赞赏。我使用的类如下:

[DataContract]
public class Config
{
    public Config()
    {
        SerializableDictionary = new SerializableDictionary<int, string>();
    }

    [DataMember]
    public SerializableDictionary<int, string> SerializableDictionary { get; set; }
}

[CollectionDataContract(Name = "SerializableDictionary", ItemName = "DictionaryItem", KeyName = "Key", ValueName = "Value")]
public sealed class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{

}

我的 XML:

<?xml version="1.0" encoding="utf-8"?>
<Config xmlns="http://TestNameSpace" >
  <SerializableDictionary >
    <DictionaryItem>
      <Key>1</Key>
      <Value>one</Value>
    </DictionaryItem>
    <DictionaryItem>
      <Key>2</Key>
      <Value>two</Value>
    </DictionaryItem>
    <DictionaryItem>
      <Key>3</Key>
      <Value>three</Value>
    </DictionaryItem>
    <DictionaryItem>
      <Key>4</Key>
      <Value>four</Value>
    </DictionaryItem>
    <DictionaryItem>
      <Key>5</Key>
      <Value>five</Value>
    </DictionaryItem>
    <DictionaryItem>
      <Key>6</Key>
      <Value>six</Value>
    </DictionaryItem>
  </SerializableDictionary>
</Config>

调用方法:

private static void Main(string[] args)
{
    Config config = null;
    using (var stream = new FileStream(
        Path.GetDirectoryName(
            Assembly.GetExecutingAssembly()
                    .Location) + "\\Dictionary.xml", FileMode.Open))
    using (var reader = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas()))
    {
        var serializer = new DataContractSerializer(typeof(Config), "Config", "http://TestNameSpace");

        config = (Config)serializer.ReadObject(reader);
    }

    foreach (var obj in config.SerializableDictionary)
        Console.WriteLine(obj.Value);

}

【问题讨论】:

    标签: c# xml wcf dictionary datacontractserializer


    【解决方案1】:

    为了弄清楚这一点,我创建了一个 Encode 方法,该方法使用您为 Config 类创建的相同 DataContract 进行编码。

    public static void Encode()
    {
      var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\dataOut.xml";
      using (var stream = new FileStream(path, FileMode.OpenOrCreate))
      {
        var serializer = new DataContractSerializer(typeof(Config), "Config", "http://TestNameSpace");
    
        serializer.WriteObject(stream, new Config(){SerializableDictionary = new SerializableDictionary<int, string> { { 1, "hello" }, { 2, "world"} }});
      }
    }
    

    查看输出后,很明显问题是子类型的命名空间问题。

    <Config xmlns="http://TestNameSpace" xmlns:a="http://schemas.datacontract.org/2004/07/DeserializeDictionary" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <a:SerializableDictionary>
        <a:DictionaryItem>
          <a:Key>1</a:Key>
          <a:Value>hello</a:Value>
        </a:DictionaryItem>
        <a:DictionaryItem>
          <a:Key>2</a:Key>
          <a:Value>world</a:Value>
        </a:DictionaryItem>
      </a:SerializableDictionary>
    </Config>
    

    我首先将Namespace = "http://TestNameSpace" 添加到SerializableDictionary 的CollectionDataContract,但这并没有解决它。只有在我也将Namespace = "http://TestNameSpace" 添加到 Config 的 DataContract 之后,它才会序列化您创建 XML 文件的方式。

    这里是更新后的 Config 和 SerializableDictionary 让它为我工作:

    [DataContract(Namespace = "http://TestNameSpace")]
    public class Config
    {
      public Config()
      {
        SerializableDictionary = new SerializableDictionary<int, string>();
      }
    
      [DataMember]
      public SerializableDictionary<int, string> SerializableDictionary { get; set; }
    }
    
    [CollectionDataContract(Name = "SerializableDictionary", ItemName = "DictionaryItem", KeyName = "Key", ValueName = "Value", Namespace = "http://TestNameSpace")]
    public sealed class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>
    {
    
    }
    

    【讨论】:

    • 在阅读您的答案时,我意识到我真的不了解 xml 中命名空间的概念。首先,感谢您帮助我意识到我需要了解 XML 命名空间以及它们为何存在。其次,这可能是问题所在,我会在早上第一件事检查它。现在,在确认这是问题所在后,我将在明天投票并接受。再次感谢您。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-14
    • 2011-04-11
    • 1970-01-01
    相关资源
    最近更新 更多