Utilisation de SsortingngWriter pour la sérialisation XML

Je recherche actuellement un moyen facile de sérialiser des objects (en C # 3).

J’ai googlé quelques exemples et est venu avec quelque chose comme:

MemoryStream memoryStream = new MemoryStream ( ); XmlSerializer xs = new XmlSerializer ( typeof ( MyObject) ); XmlTextWriter xmlTextWriter = new XmlTextWriter ( memoryStream, Encoding.UTF8 ); xs.Serialize ( xmlTextWriter, myObject); ssortingng result = Encoding.UTF8.GetSsortingng(memoryStream .ToArray()); 

Après avoir lu cette question, je me suis demandé pourquoi utiliser SsortingngWriter? Cela semble beaucoup plus facile.

 XmlSerializer ser = new XmlSerializer(typeof(MyObject)); SsortingngWriter writer = new SsortingngWriter(); ser.Serialize(writer, myObject); serializedValue = writer.ToSsortingng(); 

Un autre problème était que le premier exemple généré XML, je ne pouvais pas simplement écrire dans une colonne XML de SQL Server 2005 DB.

La première question est la suivante: y a-t-il une raison pour laquelle je ne devrais pas utiliser SsortingngWriter pour sérialiser un object lorsque j’en ai besoin comme chaîne après? Je n’ai jamais trouvé de résultat en utilisant SsortingngWriter lors de la recherche sur Google.

La seconde est, bien sûr: Si vous ne devriez pas le faire avec SsortingngWriter (pour quelque raison que ce soit), quelle serait la bonne façon?


Une addition:

Comme cela a déjà été mentionné par les deux réponses, je vais aller plus loin dans le problème XML vers DB.

En écrivant dans la firebase database, j’ai eu l’exception suivante:

System.Data.SqlClient.SqlException: parsing XML: ligne 1, caractère 38, impossible de changer le codage

Pour ficelle

  

J’ai pris la chaîne créée à partir de XmlTextWriter et je viens de la mettre au format XML. Celui-ci n’a pas fonctionné (ni avec l’insertion manuelle dans le DB).

Après, j’ai essayé l’insertion manuelle (en écrivant simplement INSERT INTO …) avec encoding = “utf-16” qui a également échoué. Suppression de l’encodage totalement fonctionné alors. Après cela, je suis revenu au code SsortingngWriter et le tour est joué – ça a fonctionné.

Problème: je ne comprends pas vraiment pourquoi.

chez Christian Hayter: Avec ces tests, je ne suis pas sûr de devoir utiliser utf-16 pour écrire dans la firebase database. Le codage en UTF-16 (dans la balise XML) ne fonctionnerait-il pas alors?

Lors de la sérialisation d’un document XML sur une chaîne .NET, le codage doit être défini sur UTF-16. Les chaînes sont stockées en UTF-16 en interne, c’est donc le seul encodage qui soit logique. Si vous souhaitez stocker des données dans un encodage différent, utilisez plutôt un tableau d’octets.

SQL Server fonctionne sur un principe similaire; toute chaîne transmise dans une colonne xml doit être codée en UTF-16. SQL Server rejettera toute chaîne où la déclaration XML ne spécifie pas UTF-16. Si la déclaration XML n’est pas présente, la norme XML exige qu’elle soit définie par défaut sur UTF-8. SQL Server le rejettera également.

Gardant cela à l’esprit, voici quelques méthodes utiles pour effectuer la conversion.

 public static ssortingng Serialize(T value) { if(value == null) { return null; } XmlSerializer serializer = new XmlSerializer(typeof(T)); XmlWriterSettings settings = new XmlWriterSettings() { Encoding = new UnicodeEncoding(false, false), // no BOM in a .NET ssortingng Indent = false, OmitXmlDeclaration = false }; using(SsortingngWriter textWriter = new SsortingngWriter()) { using(XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings)) { serializer.Serialize(xmlWriter, value); } return textWriter.ToSsortingng(); } } public static T Deserialize(ssortingng xml) { if(ssortingng.IsNullOrEmpty(xml)) { return default(T); } XmlSerializer serializer = new XmlSerializer(typeof(T)); XmlReaderSettings settings = new XmlReaderSettings(); // No settings need modifying here using(SsortingngReader textReader = new SsortingngReader(xml)) { using(XmlReader xmlReader = XmlReader.Create(textReader, settings)) { return (T) serializer.Deserialize(xmlReader); } } } 

L’un des problèmes de SsortingngWriter est que, par défaut, il ne vous permet pas de définir l’encodage qu’il annonce – vous pouvez donc vous retrouver avec un document XML annonçant son encodage en UTF-16, ce qui signifie que vous devez l’encoder comme UTF-16 si vous l’écrivez dans un fichier. J’ai un petit cours pour vous aider avec ça:

 public sealed class SsortingngWriterWithEncoding : SsortingngWriter { public override Encoding Encoding { get; } public SsortingngWriterWithEncoding (Encoding encoding) { Encoding = encoding; } } 

Ou si vous avez seulement besoin de UTF-8 (ce dont j’ai souvent besoin):

 public sealed class Utf8SsortingngWriter : SsortingngWriter { public override Encoding Encoding => Encoding.UTF8; } 

Pour ce qui est de savoir pourquoi vous ne pouviez pas enregistrer votre XML dans la firebase database, vous devrez nous donner plus de détails sur ce qui s’est passé lorsque vous avez essayé, si vous voulez que nous puissions le diagnostiquer / réparer.

Tout d’abord, méfiez-vous de trouver des exemples anciens. Vous en avez trouvé un qui utilise XmlTextWriter , qui est déconseillé à partir de .NET 2.0. XmlWriter.Create doit être utilisé à la place.

Voici un exemple de sérialisation d’un object dans une colonne XML:

 public void SerializeToXmlColumn(object obj) { using (var outputStream = new MemoryStream()) { using (var writer = XmlWriter.Create(outputStream)) { var serializer = new XmlSerializer(obj.GetType()); serializer.Serialize(writer, obj); } outputStream.Position = 0; using (var conn = new SqlConnection(Settings.Default.ConnectionSsortingng)) { conn.Open(); const ssortingng INSERT_COMMAND = @"INSERT INTO XmlStore (Data) VALUES (@Data)"; using (var cmd = new SqlCommand(INSERT_COMMAND, conn)) { using (var reader = XmlReader.Create(outputStream)) { var xml = new SqlXml(reader); cmd.Parameters.Clear(); cmd.Parameters.AddWithValue("@Data", xml); cmd.ExecuteNonQuery(); } } } } } 
 public static T DeserializeFromXml(ssortingng xml) { T result; XmlSerializerFactory serializerFactory = new XmlSerializerFactory(); XmlSerializer serializer =serializerFactory.CreateSerializer(typeof(T)); using (SsortingngReader sr3 = new SsortingngReader(xml)) { XmlReaderSettings settings = new XmlReaderSettings() { CheckCharacters = false // default value is true; }; using (XmlReader xr3 = XmlTextReader.Create(sr3, settings)) { result = (T)serializer.Deserialize(xr3); } } return result; } 

Il a peut-être été couvert ailleurs, mais le simple fait de changer la ligne de codage de la source XML en ‘utf-16’ permet d’insérer le XML dans un type SQL Server ‘xml’data.

 using (DataSetTableAdapters.SQSTableAdapter tbl_SQS = new DataSetTableAdapters.SQSTableAdapter()) { try { bodyXML = @""; bodyXMLutf16 = bodyXML.Replace("UTF-8", "UTF-16"); tbl_SQS.Insert(messageID, receiptHandle, md5OfBody, bodyXMLutf16, sourceType); } catch (System.Data.SqlClient.SqlException ex) { Console.WriteLine(ex.Message); Console.ReadLine(); } } 

Le résultat est que tout le texte XML est inséré dans le champ de type de données ‘xml’ mais la ligne ‘en-tête’ est supprimée. Ce que vous voyez dans le résultat est juste

  

L’utilisation de la méthode de sérialisation décrite dans l’entrée “Répondu” permet d’inclure l’en-tête d’origine dans le champ cible, mais le texte XML restant est placé dans une XML .

L’adaptateur de table dans le code est une classe créée automatiquement à l’aide de Visual Studio 2013 “Assistant Ajout d’une nouvelle source de données. Les cinq parameters de la méthode d’insertion correspondent aux champs d’une table SQL Server.