XmlSerialized<T> and BinarySerialized<T>

by Jon Davis 21. January 2009 20:46

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;
    }
}

 

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

C# | Software Development

Add comment


(Will show your Gravatar icon)  

  Country flag

biuquote
  • Comment
  • Preview
Loading




 

Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen

About the author

Jon Davis (aka "stimpy77") has been a programmer, developer, and consultant for web and Windows software solutions professionally since 1997, with experience ranging from OS and hardware support to DHTML programming to IIS/ASP web apps to Java network programming to Visual Basic applications to C# desktop apps.
 
Software in all forms is also his sole hobby, whether playing PC games or tinkering with programming them. "I was playing Defender on the Commodore 64," he reminisces, "when I decided at the age of 12 or so that I want to be a computer programmer when I grow up."

Jon was previously employed as a senior .NET developer at a very well-known Internet services company whom you're more likely than not to have directly done business with. However, this blog and all of jondavis.net have no affiliation with, and are not representative of, his former employer in any way.

Contact Me 


Tag cloud

Calendar

<<  April 2014  >>
MoTuWeThFrSaSu
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

View posts in large calendar