Here are a couple classes that I threw together for web services and WCF usage where the client is using the same data class library as the server. Microsoft auto-serializes stuff, but when serializing explicitly I prefer to retain an explicit type reference rather passing and manually deserializing a string or byte array. In other words, if I see a web service API return a string or byte[] as an XML or binary serialization of a complex class, I get cranky, because the client should know, without having to use external documentation, how the deserialization is type-mapped.
I'm sure there are a bunch of other uses for these, like saving an object graph to disk in two lines of code, etc. In fact, I'm also using XmlSerialized<T> to convert one compatible object type (full) to another object type (lightweight) and back again.
Being as these were indeed thrown together, I give no guarantees of anything. They worked for me.
Scenario:
// take ..
public string GetMyObject() {
var myObject = new MyType();
var sw = new System.IO.StringWriter();
var serializer = new XmlSerializer(typeof(MyType));
serializer.Serialize(sw, myObject);
return sw.ToString();
}
// .. which is a total pain to deserialize,
// and replace it altogether with ..
public XmlSerialized<MyType> GetMyObject() {
return new XmlSerialized<MyType>(new MyType());
}
// which can be deserialized either manually or "automagically"
// using .Deserialize().
Usage:
var myObject = new MyType();
// serialize to XML
var myXmlSerializedObject = new XmlSerialized<MyType>(myObject);
// preview the serialized value
string serializedValue = myXmlSerializedObject.SerializedValue;
// create it on the client
myXmlSerializedObject = new XmlSerialized<MyType>(serializedValue);
// and deserialized back to POCO
var myObjectAgain = myXmlSerializedObject.Deserialize();
// binary-serialized and compressed (slower CPU, smaller footprint)
var myBinarySerializedObject = new BinarySerialized<MyType>(myObject, true);
byte[] binaryValue = myBinarySerializedObject.SerializedValue;
bool is_it_compressed = myBinarySerializedObject.IsCompressed;
myObjectAgain = myBinarySerializedObject.Deserialize();
// uncompressed (faster CPU, larger footprint)
var myUncompressedSerializedObject = new BinarySerialized<MyType>(myObject, false);
byte[] uncompressedBinaryValue = myUncompressedBinarySerializedObject.SerializedValue;
is_it_compressed = myBinarySerializedObject.IsCompressed;
myObjectAgain = myUncompressedBinarySerializedObject.Deserialize();
The classes:
[Serializable]
[DataContract]
public class XmlSerialized<T>
{
public XmlSerialized() { }
public XmlSerialized(string serializedValue)
{
this.SerializedValue = serializedValue;
}
public XmlSerialized(T value)
{
Stream stream = new MemoryStream();
Serializer.Serialize(stream, value);
stream.Seek(0, SeekOrigin.Begin);
StreamReader sr = new StreamReader(stream);
this.SerializedValue = sr.ReadToEnd();
sr.Close();
stream.Close();
}
[System.Xml.Serialization.XmlIgnore]
private string _serializedValue = null;
[System.Xml.Serialization.XmlElement]
[DataMember]
public string SerializedValue
{
get { return _serializedValue; }
set { _serializedValue = value; }
}
public T Deserialize()
{
Stream s = new MemoryStream();
StreamWriter sw = new StreamWriter(s);
sw.Write(this.SerializedValue);
sw.Flush();
s.Seek(0, SeekOrigin.Begin);
T value = (T)Serializer.Deserialize(s);
return value;
}
private static XmlSerializer _Serializer = null;
private static XmlSerializer Serializer
{
get
{
if (_Serializer == null) _Serializer = new XmlSerializer(typeof(T));
return _Serializer;
}
}
public virtual To_T ConvertTo<To_T>()
{
var toObj = new XmlSerialized<To_T>(this.SerializedValue);
return toObj.Deserialize();
}
public virtual T ConvertFrom<FromT>(FromT obj)
{
var fromObj = new XmlSerialized<FromT>(obj);
this.SerializedValue = fromObj.SerializedValue;
return this.Deserialize();
}
}
[Serializable]
[DataContract]
public class BinarySerialized<T>
{
public bool IsCompressed { get; set; }
public BinarySerialized(T value, bool compressed)
{
this.IsCompressed = compressed;
var bf = new BinaryFormatter();
var ms = new MemoryStream();
bf.Serialize(ms, value);
byte[] bytes = ms.ToArray();
SerializedValue = compressed ? Compress(bytes) : bytes;
}
public BinarySerialized(T value)
: this(value, true) {}
public BinarySerialized(byte[] serializedValue)
{
this.SerializedValue = serializedValue;
}
public BinarySerialized() { }
[DataMember]
public byte[] SerializedValue { get; set; }
public T Deserialize()
{
byte[] bytes = IsCompressed
? Decompress(SerializedValue)
: SerializedValue;
var ms = new MemoryStream(bytes);
ms.Position = 0;
var bf = new BinaryFormatter();
T retval = (T)bf.Deserialize(ms);
return retval;
}
protected virtual byte[] Compress(byte[] byteArray)
{
//Prepare for compress
System.IO.MemoryStream ms = new System.IO.MemoryStream();
System.IO.Compression.GZipStream sw = new System.IO.Compression.GZipStream(ms,
System.IO.Compression.CompressionMode.Compress);
//Compress
sw.Write(byteArray, 0, byteArray.Length);
sw.Flush();
sw.Close();
return ms.ToArray();
}
protected virtual byte[] Decompress(byte[] byteArray)
{
//Prepare for decompress
var ms = new System.IO.MemoryStream(byteArray);
ms.Position = 0;
var sr = new System.IO.Compression.GZipStream(ms,
System.IO.Compression.CompressionMode.Decompress);
//Reset variable to collect uncompressed result
int buffer_length = 100;
byteArray = new byte[buffer_length];
//Decompress
int offset = 0;
while (true)
{
if (offset + buffer_length > byteArray.Length)
{
byte[] newArray = new byte[offset + buffer_length];
Array.Copy(byteArray, newArray, byteArray.Length);
byteArray = newArray;
}
int rByte = sr.Read(byteArray, offset, buffer_length);
if (rByte == 0)
{
byte[] retval = new byte[offset];
Array.Copy(byteArray, retval, offset);
byteArray = retval;
break;
}
offset += rByte;
}
return byteArray;
}
}