Reputation: 47
I have been banging my head on this one for a bit. It seems like it must be a simple solution but I have searched the internet and tried quite a few things.
I have a complex object which includes a string list that needs to be serialized into xml and then deserialized.
The serialization code has long since been part of the application and works in countless other scenarios but the issue here appears to be that one of the elements in the string list is a mere new line character (i.e. "\n").
It is my understanding, based on my research, it is serializing as expected (see below) but after deserialization the element contains an empty string (i.e. "") instead of "\n".
Here is the code...
public DoStuff(ItemTypeObj item)
{
string myItem = XmlSerialize<ItemType>(item);
ItemTypeObj myNewItemTypeObj = XmlDeserialize<CustomItem>(myItem)
}
public static string XmlSerialize<T>(T objectToSerialize)
{
string ret = string.Empty;
XmlSerializer s = new XmlSerializer(typeof(T));
using (MemoryStream ms = new MemoryStream())
{
s.Serialize(ms, objectToSerialize);
ms.Position = 0;
using (StreamReader sr = new StreamReader(ms))
{
sRet = sr.ReadToEnd();
}
}
return ret;
}
public static T XmlDeserialize<T>(string serializedObject)
{
T retVal = default(T);
byte[] ba = ASCIIEncoding.UTF8.GetBytes(serializedObject);
using (MemoryStream ms = new MemoryStream(ba))
{
XmlSerializer s = new XmlSerializer(typeof(T));
retVal = (T)s.Deserialize(ms);
}
return retVal;
}
To give you an idea of the data sent in, ItemTypeObj is the object which includes a string List. The string list can be variable length but sample data could look like this...
[0] = "Zero element text \n"
[1] = "[element1]"
[2] = "\n"
[3] = "[element3]"
[4] = "\n"
[5] = "[element5]"
When serialized it will look like this (which seems correct to me):
<Text>
<string>Zero element text
</string>
<string>[element1]</string>
<string>
</string>
<string>[element3]</string>
<string>
</string>
<string>[element5]</string>
<Text>
From what I've read the newlines are represented as expected in the xml above. The issue is after it is deserialized the string list is this:
[0] = "Zero element text \n"
[1] = "[element1]"
[2] = ""
[3] = "[element3]"
[4] = ""
[5] = "[element5]"
Only the newline characters in the elements that also have text (e.g. [0]) will still exist. The other two are replaced with empty string. If I add text to those elements the new line will be retained.
Looking at the byte array in the deserialization, the array element at the location in the serialized string where the "\n" was turns into a 10 (aka LF, new line). Then that does not successfully get turned into "\n" in the Deserialize. Perhaps that is too much to ask.
Any insight would be most appreciated. Thanks.
Upvotes: 0
Views: 1584
Reputation: 21245
You'll need to use the XmlReader
and XmlWriter
classes or the DataContractSerializer
.
See: How to keep XmlSerializer from killing NewLines in Strings?
public static string XmlSerialize<T>(T objectToSerialize)
{
XmlSerializer s = new XmlSerializer(typeof(T));
var settings = new XmlWriterSettings
{
NewLineHandling = NewLineHandling.Entitize
};
using(var stream = new StringWriter())
using(var writer = XmlWriter.Create(stream, settings))
{
s.Serialize(writer, objectToSerialize);
return stream.ToString();
}
}
public static T XmlDeserialize<T>(string serializedObject)
{
XmlSerializer s = new XmlSerializer(typeof(T));
using(var stream = new StringReader(serializedObject))
using(var reader = XmlReader.Create(stream))
{
return (T)s.Deserialize(reader);
}
}
Usage:
public class Foo
{
public string Bar { get; set; }
}
var foo = new Foo { Bar = "\n" };
var result = XmlSerialize(foo);
Console.WriteLine(result);
var newFoo = XmlDeserialize<Foo>(result);
Console.WriteLine(newFoo.Bar);
Debug.Assert(newFoo.Bar == "\n");
Upvotes: 2