web-dev-qa-db-fra.com

Utilisation de DataContractSerializer pour sérialiser, mais impossible de désérialiser

J'ai les 2 fonctions suivantes:

public static string Serialize(object obj)
{
    DataContractSerializer serializer = new DataContractSerializer(obj.GetType());
    MemoryStream memoryStream = new MemoryStream();
    serializer.WriteObject(memoryStream, obj);
    return Encoding.UTF8.GetString(memoryStream.GetBuffer());
}

public static object Deserialize(string xml, Type toType)
{
    MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(xml));
   // memoryStream.Position = 0L;
    XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(memoryStream, Encoding.UTF8, new XmlDictionaryReaderQuotas(), null);
    DataContractSerializer dataContractSerializer = new DataContractSerializer(toType);
    return dataContractSerializer.ReadObject(reader);
}

Le premier semble sérialiser un objet avec une chaîne xml sans problème. Le XML semble valide, pas de balises brisées, pas d'espaces blancs au début ou à la fin, etc. Maintenant, la deuxième fonction ne veut pas désérialiser ma chaîne xml vers l'objet. Sur la dernière ligne je reçois:

Une erreur s'est produite lors de la désérialisation de l'objet de type [MON TYPE D'OBJET ICI]. Les données au niveau racine ne sont pas valides. Ligne 1, position 1.

Qu'est-ce que je fais mal? J'ai essayé de réécrire la fonction Deserialize plusieurs fois, et cela semble toujours être le même type d'erreur. Merci!

Oh, et voici comment j'appelle les 2 fonctions:

SomeObject so = new SomeObject();
string temp = SerializationManager.Serialize(so);
so = (SomeObject)SerializationManager.Deserialize(temp, typeof(SomeObject));
63
Dimskiy

Voici comment je l'ai toujours fait:

    public static string Serialize(object obj) {
        using(MemoryStream memoryStream = new MemoryStream())
        using(StreamReader reader = new StreamReader(memoryStream)) {
            DataContractSerializer serializer = new DataContractSerializer(obj.GetType());
            serializer.WriteObject(memoryStream, obj);
            memoryStream.Position = 0;
            return reader.ReadToEnd();
        }
    }

    public static object Deserialize(string xml, Type toType) {
        using(Stream stream = new MemoryStream()) {
            byte[] data = System.Text.Encoding.UTF8.GetBytes(xml);
            stream.Write(data, 0, data.Length);
            stream.Position = 0;
            DataContractSerializer deserializer = new DataContractSerializer(toType);
            return deserializer.ReadObject(stream);
        }
    }
136
Ray Vernagus

Une autre solution est:

public static T Deserialize<T>(string rawXml)
{
    using (XmlReader reader = XmlReader.Create(new StringReader(rawXml)))
    {
        DataContractSerializer formatter0 = 
            new DataContractSerializer(typeof(T));
        return (T)formatter0.ReadObject(reader);
    }
}

Une remarque: il arrive parfois que xml brut contienne par exemple:

<?xml version="1.0" encoding="utf-16"?>

bien entendu, vous ne pouvez pas utiliser le codage UTF8 utilisé dans d'autres exemples.

35
rudolf_franek

J'ai fini par faire ce qui suit et ça marche.

public static string Serialize(object obj)
{
    using (MemoryStream memoryStream = new MemoryStream())
    {
        DataContractSerializer serializer = new DataContractSerializer(obj.GetType());
        serializer.WriteObject(memoryStream, obj);
        return Encoding.UTF8.GetString(memoryStream.ToArray());
    }
}

public static object Deserialize(string xml, Type toType)
{
    using (MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
    {
        XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(memoryStream, Encoding.UTF8, new XmlDictionaryReaderQuotas(), null);
        DataContractSerializer serializer = new DataContractSerializer(toType);
        return serializer.ReadObject(reader);
    }
}

Il semble que le problème majeur soit dans la fonction Serialize lors de l'appel de stream.GetBuffer (). L'appel de stream.ToArray () semble fonctionner.

33
Dimskiy