物件序列化

  • 2767
  • 0

自己實作物件序列化

因內建序列化與所需有差異,所以就自行打造:

 

序列化後的結果:

 

<?xml version="1.0" encoding="utf-16"?>
<Object TabStop="False" Text="groupBox1" Dock="Left" Location="4, 4" Margin="4, 4, 4, 4" Name="groupBox1" Size="667, 438" TabIndex="3" Padding="4, 4, 4, 4" type="System.Windows.Forms.GroupBox" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll">
  <Object TabStop="False" Text="groupBox1" Dock="Fill" Location="4, 81" Margin="4, 4, 4, 4" Name="groupBox3" Size="659, 353" TabIndex="3" Padding="4, 4, 4, 4" type="System.Windows.Forms.GroupBox" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll">
    <Object RightSideBlank="5" Culture="Chinese (Taiwan)" Dock="Bottom" Location="4, 174" Margin="4, 4, 4, 4" Name="weekCalendar1" Size="651, 175" TabIndex="3" Padding="8, 8, 8, 8" type="Workstation.WeekCalendar" assembly="D:\Projects\PlugInSample\MainApp\Workstation.exe" />
    <Object Multiline="True" Location="371, 19" Margin="4, 4, 4, 4" Name="textBox5" Size="148, 104" TabIndex="10" type="System.Windows.Forms.TextBox" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
    <Object Location="112, 106" Margin="4, 4, 4, 4" Name="textBox4" Size="148, 26" TabIndex="9" type="System.Windows.Forms.TextBox" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
    <Object Location="112, 77" Margin="4, 4, 4, 4" Name="textBox3" Size="148, 26" TabIndex="8" type="System.Windows.Forms.TextBox" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
    <Object Location="112, 48" Margin="4, 4, 4, 4" Name="textBox2" Size="148, 26" TabIndex="7" type="System.Windows.Forms.TextBox" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
    <Object Location="112, 19" Margin="4, 4, 4, 4" Name="textBox1" Size="148, 26" TabIndex="6" type="System.Windows.Forms.TextBox" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
    <Object AutoSize="True" Text="label10" Location="45, 22" Margin="4, 0, 4, 0" Name="label10" Size="59, 18" TabIndex="5" type="System.Windows.Forms.Label" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
    <Object AutoSize="True" Text="label9" Location="304, 26" Margin="4, 0, 4, 0" Name="label9" Size="50, 18" TabIndex="4" type="System.Windows.Forms.Label" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
    <Object AutoSize="True" Text="label8" Location="45, 112" Margin="4, 0, 4, 0" Name="label8" Size="50, 18" TabIndex="3" type="System.Windows.Forms.Label" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
    <Object AutoSize="True" Text="label7" Location="45, 82" Margin="4, 0, 4, 0" Name="label7" Size="50, 18" TabIndex="2" type="System.Windows.Forms.Label" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
    <Object AutoSize="True" Text="label6" Location="45, 52" Margin="4, 0, 4, 0" Name="label6" Size="50, 18" TabIndex="1" type="System.Windows.Forms.Label" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
  </Object>
  <Object TabStop="False" Text="groupBox1" Dock="Top" Location="4, 23" Margin="4, 4, 4, 4" Name="groupBox2" Size="659, 58" TabIndex="3" Padding="4, 4, 4, 4" type="System.Windows.Forms.GroupBox" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll">
    <Object AutoSize="True" Text="label5" Location="281, 28" Margin="4, 0, 4, 0" Name="label5" Size="50, 18" TabIndex="2" type="System.Windows.Forms.Label" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
    <Object AutoSize="True" Text="label4" Location="183, 28" Margin="4, 0, 4, 0" Name="label4" Size="50, 18" TabIndex="1" type="System.Windows.Forms.Label" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
    <Object AutoSize="True" Text="label3" Location="93, 28" Margin="4, 0, 4, 0" Name="label3" Size="50, 18" TabIndex="0" type="System.Windows.Forms.Label" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
  </Object>
</Object>

 

 

序列化及反序列化程式

public static void ToXml(this object obj, XmlWriter xml)
{
    var props = TypeDescriptor.GetProperties(obj);
    xml.WriteStartElement("Object");
    foreach (PropertyDescriptor p in props)
    {
        if (p.SerializationVisibility != DesignerSerializationVisibility.Visible) continue;
        if (!p.ShouldSerializeValue(obj)) continue;
        var raw = p.GetValue(obj);
        if (raw == null) continue;
        if (p.Converter == null) continue;
        var value = p.Converter.ConvertToInvariantString(raw);
        xml.WriteAttributeString(p.Name, value);
    }
    var type = TypeDescriptor.GetReflectionType(obj);
    xml.WriteAttributeString("type", type.FullName);
    xml.WriteAttributeString("assembly", type.Assembly.Location);
    if (props["Controls"] != null)
    {
        var controls = props["Controls"].GetValue(obj) as IList;
        if (controls != null && controls.Count > 0)
            foreach (var c in controls)
                ToXml(c, xml);
    }
    xml.WriteEndElement();
}
public static object CreateObject(this XmlNode node)
{
    if (node.Name != "Object") return null;
    if (node.Attributes == null) return null;
    var attr = new Dictionary<string, string>();
    foreach (XmlAttribute a in node.Attributes)
        attr[a.Name] = a.Value;
    if (!attr.ContainsKey("assembly") || !attr.ContainsKey("type")) return null;
    try
    {
        var asm = Assembly.LoadFrom(attr["assembly"]);
        var obj = asm.CreateInstance(attr["type"]);
        if (obj == null) return null;
        var props = TypeDescriptor.GetProperties(obj);
        foreach (var a in attr)
        {
            if (props[a.Key] == null) continue;
            var converter = props[a.Key].Converter;
            if (converter == null) continue;
            var value = converter.ConvertFromInvariantString(a.Value);
            if (value != null)
                props[a.Key].SetValue(obj, value);
        }
        var ctrl = obj as Control;
        if (ctrl == null) return obj;
        foreach (XmlNode childNode in node.ChildNodes)
        {
            var child = childNode.CreateObject();
            if (child == null) continue;
            var childCtrl = child as Control;
            if (childCtrl != null)
                ctrl.Controls.Add(childCtrl);
        }
        return obj;
    }
    catch (Exception)
    {
        return null;
    }
}