using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using System.Xml.Serialization;
namespace daniweb
{
public partial class frmSerial2 : Form
{
private byte[] serializedData;
public frmSerial2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ConcreteClass cc = new ConcreteClass();
cc.BaseProperty1 = "abc";
cc.BaseProperty2 = 5;
cc.BaseProperty3 = DateTime.Now;
cc.Property1 = "ssss";
cc.Property2 = 15;
cc.Property3 = DateTime.Now.AddDays(5);
cc.Property4 = 1324;
using (MemoryStream ms = new MemoryStream())
{
CustomSerializer.SerializeObject(ms, cc);
serializedData = ms.ToArray();
}
#region lets inspect our work
{
string xmlData = System.Text.ASCIIEncoding.UTF8.GetString(serializedData);
Console.WriteLine(xmlData);
System.Diagnostics.Debugger.Break();
}
#endregion
}
private void button2_Click(object sender, EventArgs e)
{
ConcreteClass cc = new ConcreteClass();
using (MemoryStream ms = new MemoryStream(serializedData))
{
ms.Position = 0;
ms.Seek(0, SeekOrigin.Begin);
CustomSerializer.DeserializeObject(ms, cc);
}
System.Diagnostics.Debugger.Break();
}
}
public class BaseClass
{
public string BaseProperty1 { get; set; }
public int BaseProperty2 { get; set; }
public DateTime BaseProperty3 { get; set; }
public BaseClass()
{
}
}
public class ConcreteClass : BaseClass
{
[CustomSerialized]
public string Property1 { get; set; }
[CustomSerialized]
public int Property2 { get; set; }
[CustomSerialized]
public DateTime Property3 { get; set; }
public long Property4 { get; set; }
public ConcreteClass()
: base()
{
}
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
internal sealed class CustomSerialized : Attribute
{
public CustomSerialized()
{
}
}
public class NameValuePair
{
public string PropertyName { get; set; }
public object PropertyValue { get; set; }
public NameValuePair() { }
public NameValuePair(string PropertyName, object PropertyValue)
: this()
{
this.PropertyName = PropertyName;
this.PropertyValue = PropertyValue;
}
}
public static class CustomSerializer
{
//.DeclaredOnly - ignored inherited members
private const BindingFlags SqlObjectBindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
private static bool IsMarkedCustomSerialzed(PropertyInfo Prop)
{
Attribute[] attrs = System.Attribute.GetCustomAttributes(Prop);
foreach (Attribute at in attrs)
{
if ((at as CustomSerialized) != null)
return true;
}
return false;
}
private static PropertyInfo[] GetProperties(object o)
{
List<PropertyInfo> result = new List<PropertyInfo>();
PropertyInfo[] properties = o.GetType().GetProperties(SqlObjectBindingFlags);
foreach (PropertyInfo pi in properties)
{
if (IsMarkedCustomSerialzed(pi) && pi.CanRead && pi.CanWrite)
result.Add(pi);
}
return result.ToArray();
}
public static void SerializeObject(Stream stream, object o)
{
PropertyInfo[] properties = GetProperties(o);
List<NameValuePair> lst = new List<NameValuePair>();
foreach (PropertyInfo pi in properties)
{
lst.Add(new NameValuePair(pi.Name, pi.GetValue(o, null)));
}
XmlSerializer ser = new XmlSerializer(typeof(List<NameValuePair>));
ser.Serialize(stream, lst);
}
//This doesn't create the object for you since we're not serializing all properties.
//It basically does "apply property changes"
public static void DeserializeObject(Stream s, object o)
{
XmlSerializer ser = new XmlSerializer(typeof(List<NameValuePair>));
List<NameValuePair> lst = (List<NameValuePair>)ser.Deserialize(s);
PropertyInfo[] properties = GetProperties(o);
foreach (PropertyInfo pi in properties)
{
NameValuePair nvp = FindInList(lst, pi.Name);
if (nvp != null)
{
pi.SetValue(o, nvp.PropertyValue, null);
}
}
}
private static NameValuePair FindInList(List<NameValuePair> searchList, string PropertyName)
{
foreach (NameValuePair nvp in searchList)
{
if (string.Compare(nvp.PropertyName, PropertyName, true) == 0)
return nvp;
}
return null;
}
}
}