使用DataContactSerializer反序列化xml Dictionary <tkey,tvalue> </tkey,tvalue>

时间:2014-09-03 20:32:35

标签: c# xml wcf dictionary datacontractserializer

我正在尝试使用Dictionary<TKey,TValue>反序列化DataContractSerializer。我没有得到例外,我的字典会回来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);

}

1 个答案:

答案 0 :(得分: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>
{

}