11
votes

C # Série XML et désérialisation

J'essaie de sérialiser un objet et de l'enregistrer dans un champ XML SQL Server 2008. J'ai aussi un code de désérialisation qui réorganise l'objet. Je suis capable de sérialiser et d'enregistrer l'objet dans la base de données, mais d'obtenir une exception «élément racine manquant».

public static class XmlSerializer
{
    public static string Serialize<T>(T item)
    {
        MemoryStream memStream = new MemoryStream();
        using (XmlTextWriter textWriter = new XmlTextWriter(memStream, Encoding.Unicode))
        {
            System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
            serializer.Serialize(textWriter, item);

            memStream = textWriter.BaseStream as MemoryStream;
        }
        if (memStream != null)
            return Encoding.Unicode.GetString(memStream.ToArray());
        else
            return null;
    }

    public static T Deserialize<T>(string xmlString)
    {
        if (string.IsNullOrWhiteSpace(xmlString))
            return default(T);

        using (MemoryStream memStream = new MemoryStream())
        {
            using (XmlTextWriter textWriter = new XmlTextWriter(memStream, Encoding.Unicode))
            {
                memStream.Position = 0;
                System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
                return (T)serializer.Deserialize(memStream);
            }
        }
    }
}


0 commentaires

3 Réponses :


0
votes

Je pense que vous devez ajouter l'en-tête XML:

public static string Serialize<T>(T item, bool includeHeader = false)
{
    MemoryStream memStream = new MemoryStream();
    using (XmlTextWriter textWriter = new XmlTextWriter(memStream, Encoding.Unicode))
    {
        System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
        serializer.Serialize(textWriter, item);

        memStream = textWriter.BaseStream as MemoryStream;
    }
    if (memStream != null)
        if (includeHeader)
        {
            return @"<?xml version=""1.0"" encoding=""utf-8"" ?>" + Environment.NewLine + Encoding.Unicode.GetString(memStream.ToArray());
        }
        else
        {
            return Encoding.Unicode.GetString(memStream.ToArray());
        }
    else
        return null;
}


2 commentaires

comment je fais ça? Le code XML a été généré lorsque je serai sérialisé l'objet.


Vous devriez être capable de l'ajouter à la sortie de la méthode Serialize.



11
votes

Dans votre code de désérialisation, vous créez un mémoire MemoryReam et XMLTextWriter, mais vous ne lui donnez pas la chaîne de désérialiser.

using (MemoryStream memStream = new MemoryStream(Encoding.Unicode.GetBytes(xmlString)))
{
    System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
    return (T)serializer.Deserialize(memStream);
}


2 commentaires

Ça a marché!! Juste curieux ... que se passait avec le textwriter?


@Kp. Le XMLTextWriter n'est pas nécessaire pour la désérialisation puisque vous ne construisez aucun XML. Dans ce cas, il a été créé avec une référence à la MemorMemstream et chargé d'utiliser Unicode mais n'a pas été référencé au-delà de sa création. J'ai également remarqué que le MemorMemstream dans le code de sérialisation n'est pas disposé. Vous devriez probablement envisager de réviser le code pour l'envelopper également dans un bloc d'utilisation.



1
votes

On dirait que vous avez eu une poignée sur Serializing to XML, prenez donc mon conseil, stockez donc le XML dans un champ de chaîne (VARCHAR, NVARCHAR, TEXT, NTEXT) et non un champ spécialisé.

Si vous faites ce petit commutateur, vous serez prêt à partir ... Aucune modification supplémentaire requise. P>

Le champ XML est soumis à des validations, et plus de quelques maux de tête, et si votre application est seulement Producteur et consommateur de ce domaine, vous pourriez aussi bien prendre ce raccourci. SQL2008 (même 2005) est suffisamment solide pour compenser les ressources que vous pourriez économiser en compilant le champ XML. p>

Cependant, Je voudrais optimiser un peu votre code, on dirait que vous avez écrit beaucoup plus de code que vous n'aviez. Par exemple, vous n'avez plus besoin de créer un champ privé pour stocker les données de votre propriété, par exemple: p> xxx pré>

fonctionnera simplement si vous l'avez écrit comme: P>

    public PersonalXml Personal { get ; set ; }


1 commentaires

Je pensais que le champ XML dans SQL Server 2008 est plus optimisé pour la requête XML. Ou puis-je aussi utiliser d'autres champs comme Varchar, Nvarchars, etc.?