2014-09-03 67 views
0

我试图反序列化一个Dictionary<TKey,TValue>DataContractSerializer。我没有得到例外,我的字典回来了null。我已经阅读了多篇文章,尝试了多个实现,但仍未找到成功。我相信这是一个非常小的东西,我错过了,真的可以使用几套眼睛来为我查看这个,也许选择它并告诉我我的问题在哪里。任何帮助是极大的赞赏。是我使用的类如下:反序列化xml字典<TKey,TValue>与DataContactSerializer

[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

为了想出解决办法,我创建了一个编码方法使用与您为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文件的方式序列化。

这里是更新了配置和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> 
{ 

} 
+0

在阅读你的答案,我意识到,我真的不理解XML命名空间的概念。首先,谢谢你帮助我认识到我需要了解XML名称空间以及它们为什么在那里。其次,这可能是问题,我会在早上第一时间检查它。现在我确认这是问题后,我会投票并接受明天。再次感谢你。 – 2014-09-04 01:19:11