2013-03-30 2 views
0

У меня есть этот класс в C#Проблемы Сериализация объекта

public class ExerciseDTO { 
    Dictionary<String, String> qa; 
    private String materialId, content, topic; 

    //constructors 

    //properties 

    public void makePersistent(String path) { 
     Stream outputStream = File.OpenWrite(path + @"\" + this.topic + ".xml"); 
     XmlSerializer serializer = new XmlSerializer(typeof(ExerciseDTO)); 
     serializer.Serialize(outputStream, this); 
     outputStream.Flush(); 
     outputStream.Close(); 
    } 
} 

Вызов метода makePersistent делает приложение сгенерирует Exeption с сообщением An error occured while reflecting object of type ExerciseDTO. Почему я не могу сериализовать экземпляры этого класса?

ответ

0
[Serializable] 
public class ExerciseDTO { 
... 
} 
  • Вы должны также иметь значение по умолчанию (аргумент бесплатно) конструктор
  • Вы должны также сделать вашу собственность общественности, если вы хотите, чтобы автоматически сериализовать его
  • сериализация словаря <> не поддерживается Однако .net существует, например, this post.

Edit: так прокомментировал следующим образом: он должен быть «сериализация Словаре <> не поддерживается класса XmlSerializer».

+0

* сериализации из словаря <> не поддерживается .net * Ты Прикалываешься??? Я даже узнал, что он не может сериализовать ссылки, указанные как типы интерфейса! WTH ??? Теперь я считаю, что это точно сказать, что .NET - самая худшая платформа, на которой я когда-либо программировал! Я никогда больше не буду использовать его для чего-либо, кроме WindowsPhone! Java превосходит далеко! –

+1

'Сериализация словаря <> не поддерживается .net' не является истинным утверждением. Более правильным утверждением является 'сериализация словаря <> не поддерживается классом XmlSerializer'. Вы можете использовать класс DataContractSerializer, который поддерживает словари. –

+0

@DarinDimitrov, мы всегда говорим в контексте, я уже предложил ссылку, чтобы сделать это в .net, поэтому вы, кажется, комментируете ..., я не знаю, я просто хочу, чтобы можно было найти полезное из моего ответа, и я также надеюсь, что люди могут найти полезную информацию из ваших комментариев. Во всяком случае, я даю вам поддержку для вашего обновленного комментария. – David

4

Почему я не могу сериализовать экземпляры этого класса?

Потому что XmlSerializer класс doesn't support serializing Dictionary<TKey, TValue> объектов недвижимости.

В качестве альтернативы вы можете использовать DataContractSerializer, который поддерживает словари.

+0

Ошибка говорит, что у нее были проблемы, отражающие объект, я думаю, что реализация отражения в платформе .NET должна быть независимой от XmlSerializer. Вы уверены, что его единственный XmlSerializer, который не может сохраняться «Словарь» или все сериализаторы? –

+1

Нет, только словарь 'XmlSerializer' не поддерживает словари. ['DataContractSerializer'] (http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx) отлично работает со словарными типами. Я обновил свой ответ, чтобы включить эту информацию. –

+0

Thats блестящий тогда; вы имеете в виду, что я могу сериализовать словарь с помощью двоичного сериализатора, правильно? Кто вообще заботится о XML? Мне просто нужно, чтобы мой объект сохранялся и извлекался. –

0

Что Дарин сказал, Dictionary не является сериализуемым по XML. Вы можете создать свой собственный XmlSerializableDictionary. В Интернете есть много хороших примеров. Вот один:

http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx

В случае ссылка умирает в будущем, копия/паста:

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Xml.Serialization; 

[XmlRoot("dictionary")] 
public class SerializableDictionary<TKey, TValue> 
    : Dictionary<TKey, TValue>, IXmlSerializable 
{ 
    #region IXmlSerializable Members 

    public System.Xml.Schema.XmlSchema GetSchema() 
    { 
     return null; 
    } 

    public void ReadXml(System.Xml.XmlReader reader) 
    { 
     XmlSerializer keySerializer = new XmlSerializer(typeof(TKey)); 
     XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue)); 
     bool wasEmpty = reader.IsEmptyElement; 

     reader.Read(); 

     if (wasEmpty) 
      return; 

     while (reader.NodeType != System.Xml.XmlNodeType.EndElement) 
     { 
      reader.ReadStartElement("item"); 
      reader.ReadStartElement("key"); 

      TKey key = (TKey)keySerializer.Deserialize(reader); 

      reader.ReadEndElement(); 
      reader.ReadStartElement("value"); 

      TValue value = (TValue)valueSerializer.Deserialize(reader); 
      reader.ReadEndElement(); 
      this.Add(key, value); 
      reader.ReadEndElement(); 
      reader.MoveToContent(); 
     } 

     reader.ReadEndElement(); 
    } 

    public void WriteXml(System.Xml.XmlWriter writer) 
    { 
     XmlSerializer keySerializer = new XmlSerializer(typeof(TKey)); 

     XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue)); 

     foreach (TKey key in this.Keys) 
     { 
      writer.WriteStartElement("item"); 

      writer.WriteStartElement("key"); 
      keySerializer.Serialize(writer, key); 
      writer.WriteEndElement(); 
      writer.WriteStartElement("value"); 
      TValue value = this[key]; 
      valueSerializer.Serialize(writer, value); 
      writer.WriteEndElement(); 
      writer.WriteEndElement(); 
     } 
    } 
    #endregion 
}