Friday, August 7, 2009

XML Serialization and Deserialization made easy.

In my previous post I described the problem with passing a local object as a webmethod argument. I briefly mentioned there're 2 ways to resolve the problem. Well here's the other one.

Using the following extension method, you can now get its XMLDocument representation by typing ".Serialize()"

Getting the same object back is extremely easy as well, simply typing ".Deserialize(OriginalSample)" OriginalSample being an object returned when calling the default constructor the object's default constructor (which you must have for .NET XML Serialization anyways)

This would also help in the webmethod call, local to proxy class conversion problem by serializing the object to XMLDocument and then deserializing into the desired proxy type. For example: "WebService.WebMethod(ObjectA.Clone(Proxy.ObjectA));"

This is the code you need:



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Xml;

namespace XMLSerializerHelperClasses
{
/// <summary>
/// This extension helps to easily and intuitively serialize objects to xml and deserialize back to object.
/// </summary>
public static class Extension
{
/// <summary>
/// XML Serilize the given object.
/// </summary>
/// <param name="O">The object to be serialized</param>
/// <returns>An xml representation of the serialized object.</returns>
public static string Serialize(this object O)
{
//Initial preparation for the object serialization. We instantiate the serializer, the memory stream and the text (xml) writer.
XmlSerializer Serializer = GetSerializer(O);


using (MemoryStream MemoryStream = new MemoryStream())
{
//Creates a unicode textwriter to the memory stream.
XmlTextWriter TextWriter = new XmlTextWriter(MemoryStream, Encoding.Unicode);

//Serialize the object into the memory stream using the textwriter.
Serializer.Serialize(TextWriter, O);

//Returns the string representation of the object.
//NOTE: The prefix of the string is some unrecognized character, and must be trimmed for proper functioning.
return Encoding.Unicode.GetString(MemoryStream.ToArray(), 0, (int)MemoryStream.Length).Substring(1);
}
}

/// <summary>
/// XML Serilize the given object.
/// </summary>
/// <param name="O">The object to be serialized</param>
/// <param name="Namespace">The namespace of the object, for SOA</param>
/// <returns>An xml representation of the serialized object.</returns>
public static string Serialize(this object O, string Namespace)
{
//Initial preparation for the object serialization. We instantiate the serializer, the memory stream and the text (xml) writer.
XmlSerializer Serializer = new XmlSerializer(O.GetType(), Namespace);


using (MemoryStream MemoryStream = new MemoryStream())
{
//Creates a unicode textwriter to the memory stream.
XmlTextWriter TextWriter = new XmlTextWriter(MemoryStream, Encoding.Unicode);

//Serialize the object into the memory stream using the textwriter.
Serializer.Serialize(TextWriter, O);

//Returns the string representation of the object.
//NOTE: The prefix of the string is some unrecognized character, and must be trimmed for proper functioning.
return Encoding.Unicode.GetString(MemoryStream.ToArray(), 0, (int)MemoryStream.Length).Substring(1);
}
}


/// <summary>
/// XML Serilize the given object.
/// </summary>
/// <param name="O">The object to be deserialized</param>
/// <param name="TargetObject">The target object for deserialization.</param>
/// <returns>An object representation of the xml serialized object.</returns>
public static T DeSerialize<T>(this string O, T TargetObject)
{
//Initial preparation for the object serialization. We instantiate the serializer, the memory stream and the text (xml) writer.
XmlSerializer Serializer = GetSerializer(TargetObject);

using (MemoryStream MemoryStream = new MemoryStream())
{
//Converts string to stream.
XmlTextWriter TextWriter = new XmlTextWriter(MemoryStream, Encoding.Unicode);
TextWriter.WriteRaw(O);
TextWriter.Flush();
MemoryStream.Seek(0, 0);
StreamReader Reader = new StreamReader(MemoryStream, Encoding.Unicode);
//DeSerialize the unicode reader.
return (T)Serializer.Deserialize(Reader);
}
}


/// <summary>
/// XML Serilize the given object.
/// </summary>
/// <param name="O">The object to be deserialized</param>
/// <param name="TargetObject">The target object for deserialization.</param>
/// <param name="Namespace">The target object's namespace, usually "http://tempury.org"</param>
/// <returns>An object representation of the xml serialized object.</returns>
public static T DeSerialize<T>(this string O, T TargetObject, string Namespace)
{
//Initial preparation for the object serialization. We instantiate the serializer, the memory stream and the text (xml) writer.
XmlSerializer Serializer = new XmlSerializer(TargetObject.GetType(), Namespace);

using (MemoryStream MemoryStream = new MemoryStream())
{
//Converts string to stream.
XmlTextWriter TextWriter = new XmlTextWriter(MemoryStream, Encoding.Unicode);
TextWriter.WriteRaw(O);
TextWriter.Flush();
MemoryStream.Seek(0, 0);
StreamReader Reader = new StreamReader(MemoryStream, Encoding.Unicode);
//DeSerialize the unicode reader.
return (T)Serializer.Deserialize(Reader);
}
}

/// <summary>
///
/// </summary>
/// <param name="O"></param>
/// <returns></returns>
private static XmlSerializer GetSerializer(Object O)
{
//Should not return null.
XmlSerializer Serializer = null;
Serializer = new XmlSerializer(O.GetType());
return Serializer;
}


/// <summary>
/// Clones an object using serialization - deserialization technique.
/// NOTE: All limitations pertaining to xml serialization/deserialization applies here, objects must have default constructor and public members.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="Object"></param>
/// <returns></returns>
public static T Clone<T>(this T Object)
{
return Object.Serialize().DeSerialize(Object);
}
}
}

No comments:

Post a Comment