2014-09-03 2 views
0

Я пытаюсь Deserialize Dictionary<TKey,TValue> с DataContractSerializer. Я не получаю исключения, мой словарь возвращается null. Я прочитал несколько сообщений, попробовал несколько реализаций и до сих пор не нашел успеха. Я уверен, что это что-то очень маленькое, что я пропал без вести и действительно могу использовать несколько наборов глаз, чтобы рассмотреть это для меня и, возможно, разобрать его и сказать, где моя проблема. Любая помощь приветствуется. Классы я использую следующие:Deserializing xml Dictionary <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

Для того, чтобы понять это, я создал метод Encode, что кодирует, используя тот же DataContract, который был создан для класса Config.

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" к CollectionDataContract в SerializableDictionary, но это не решить. Только после того, как я также добавил Namespace = "http://TestNameSpace" в DataContract Config, он сериализовал способ создания вашего 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> 
{ 

} 
+0

Читая ваш ответ, я понял, что я действительно не понимаю концепцию пространств имен в XML. Итак, во-первых, спасибо, что помогли мне понять, что мне нужно узнать о пространствах имен XML и о том, почему они там. Во-вторых, это, вероятно, проблема, и я буду проверять ее первым делом с утра. На данный момент я буду голосовать и принять завтра после подтверждения того, что это проблема. Еще раз спасибо. –

Смежные вопросы