Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using StringWriter for XML Serialization

I'm currently searching for an easy way to serialize objects (in C# 3).

I googled some examples and came up with something like:

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

After reading this question I asked myself, why not using StringWriter? It seems much easier.

XmlSerializer ser = new XmlSerializer(typeof(MyObject)); StringWriter writer = new StringWriter(); ser.Serialize(writer, myObject); serializedValue = writer.ToString(); 

Another Problem was, that the first example generated XML I could not just write into an XML column of SQL Server 2005 DB.

The first question is: Is there a reason why I shouldn't use StringWriter to serialize an Object when I need it as a string afterwards? I never found a result using StringWriter when googling.

The second is, of course: If you should not do it with StringWriter (for whatever reasons), which would be a good and correct way?


Addition:

As it was already mentioned by both answers, I'll further go into the XML to DB problem.

When writing to the Database I got the following exception:

System.Data.SqlClient.SqlException: XML parsing: line 1, character 38, unable to switch the encoding

For string

<?xml version="1.0" encoding="utf-8"?><test/> 

I took the string created from the XmlTextWriter and just put as xml there. This one did not work (neither with manual insertion into the DB).

Afterwards I tried manual insertion (just writing INSERT INTO ... ) with encoding="utf-16" which also failed. Removing the encoding totally worked then. After that result I switched back to the StringWriter code and voila - it worked.

Problem: I don't really understand why.

at Christian Hayter: With those tests I'm not sure that I have to use utf-16 to write to the DB. Wouldn't setting the encoding to UTF-16 (in the xml tag) work then?

like image 247
StampedeXV Avatar asked Oct 14 '09 07:10

StampedeXV


People also ask

How do you serialize an object in XML?

Follow these steps to create a console application that creates an object, and then serializes its state to XML: In Visual C#, create a new Console Application project. On the Project menu, select Add Class to add a new class to the project. In the Add New Item dialog box, change the name of the class to clsPerson.

What is StringWriter C#?

StringWriter enables you to write to a string synchronously or asynchronously. You can write a character at a time with the Write(Char) or the WriteAsync(Char) method, a string at a time using the Write(String) or the WriteAsync(String) method.

What is XML serialization and Deserialization in C#?

Serialization is a process by which an object's state is transformed in some serial data format, such as XML or binary format. Deserialization, on the other hand, is used to convert the byte of data, such as XML or binary data, to object type.


2 Answers

One problem with StringWriter is that by default it doesn't let you set the encoding which it advertises - so you can end up with an XML document advertising its encoding as UTF-16, which means you need to encode it as UTF-16 if you write it to a file. I have a small class to help with that though:

public sealed class StringWriterWithEncoding : StringWriter {     public override Encoding Encoding { get; }      public StringWriterWithEncoding (Encoding encoding)     {         Encoding = encoding;     }     } 

Or if you only need UTF-8 (which is all I often need):

public sealed class Utf8StringWriter : StringWriter {     public override Encoding Encoding => Encoding.UTF8; } 

As for why you couldn't save your XML to the database - you'll have to give us more details about what happened when you tried, if you want us to be able to diagnose/fix it.

like image 182
Jon Skeet Avatar answered Sep 22 '22 16:09

Jon Skeet


When serialising an XML document to a .NET string, the encoding must be set to UTF-16. Strings are stored as UTF-16 internally, so this is the only encoding that makes sense. If you want to store data in a different encoding, you use a byte array instead.

SQL Server works on a similar principle; any string passed into an xml column must be encoded as UTF-16. SQL Server will reject any string where the XML declaration does not specify UTF-16. If the XML declaration is not present, then the XML standard requires that it default to UTF-8, so SQL Server will reject that as well.

Bearing this in mind, here are some utility methods for doing the conversion.

public static string Serialize<T>(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 string         Indent = false,         OmitXmlDeclaration = false     };      using(StringWriter textWriter = new StringWriter()) {         using(XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings)) {             serializer.Serialize(xmlWriter, value);         }         return textWriter.ToString();     } }  public static T Deserialize<T>(string xml) {      if(string.IsNullOrEmpty(xml)) {         return default(T);     }      XmlSerializer serializer = new XmlSerializer(typeof(T));      XmlReaderSettings settings = new XmlReaderSettings();     // No settings need modifying here      using(StringReader textReader = new StringReader(xml)) {         using(XmlReader xmlReader = XmlReader.Create(textReader, settings)) {             return (T) serializer.Deserialize(xmlReader);         }     } } 
like image 42
Christian Hayter Avatar answered Sep 24 '22 16:09

Christian Hayter