C# XML序列化和反序列化(DataContractSerializer)

概述

     XML序列化和反序列化是C#的常用技术,实现的方式有很多种,序列化即将对象转化为便于传输的数据格式, 常见的方法有:二进制,字节数组,json字符串,xml字符串等。今天主要通过DataContractSerializer类的WriteObject和ReadObject方法实现.上次讲过XmlSerializer序列化和反序列化,请参考:

C# XML序列化和反序列化(XmlSerializer)

代码实现

     前台XMAL: 逻辑很简单,主要通过绑定DisplayInfo显示相关信息

<UserControl x:Class="Caliburn.Micro.Hello.DataContractSerializerView"             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"              xmlns:local="clr-namespace:Caliburn.Micro.Hello"             mc:Ignorable="d"              d:DesignHeight="450" d:DesignWidth="800">    <Grid>        <TextBlock  Background="White"  Height="450"  MinWidth="210"                     VerticalAlignment="Top" TextWrapping="NoWrap" Name="DisplayInfo"/>    </Grid></UserControl>

后台cs代码:

using System;using System.IO;using System.Reflection;using System.Runtime.Serialization;using System.Text;
namespace Caliburn.Micro.Hello{    public class DataContractSerializerViewModel : Screen, IViewModel    {        private StringBuilder stringBuilder = new StringBuilder();        public string DisplayInfo { get; set; }
        public DataContractSerializerViewModel()        {            DisplayName = "DataContractSerializer";
            InitData();
            stringBuilder.AppendLine("success");            DisplayInfo = stringBuilder.ToString();        }
        public void InitData()        {            string fileName = "Programmers.dat";            Stream fs = null;            fs = FileReset(fs, fileName);
            //序列化            DataContractSerializer dataContractSerializer = new DataContractSerializer(typeof(Person));            dataContractSerializer.WriteObject(fs, new Person("zzz", "yyy", 555,                new lesson() { English = "eee", Chinese = "ccc" }));
            //反序列化            fs.Position = 0;            var p = (Person)dataContractSerializer.ReadObject(fs);            //Console.WriteLine($"{p.FirstName},{p.LastName},{p.ID},{p.lesson}");            stringBuilder.AppendLine($"{p.FirstName},{p.LastName},{p.ID},{p.lesson}");
            //自定义属性            Person newPerson = new Person();            Type type = typeof(Person);            InformationAttribute informationAttribute;            //Querying Class Attributes            foreach (Attribute attr in type.GetCustomAttributes(true))            {                informationAttribute = attr as InformationAttribute;                if (null != informationAttribute)                {                    //Console.WriteLine("Description of AnyClass:\n{0} {1}",                    //    informationAttribute.Description, informationAttribute.DefaultValue);                    stringBuilder.AppendLine($"Description of AnyClass:\n{informationAttribute.Description} " +                        $"{informationAttribute.DefaultValue}");                }            }            //Querying Class-Method Attributes            foreach (MethodInfo method in type.GetMethods())            {                foreach (Attribute attr in method.GetCustomAttributes(true))                {                    informationAttribute = attr as InformationAttribute;                    if (null != informationAttribute)                    {                        //Console.WriteLine("Description of {0}:\n{1} ", method.Name, informationAttribute.Description);                        stringBuilder.AppendLine($"Description of {method.Name}:\n{informationAttribute.Description} ");                    }                }            }
            //Querying Class-Field (only public) Attributes            foreach (FieldInfo field in type.GetFields())            {                foreach (Attribute attr in field.GetCustomAttributes(true))                {                    informationAttribute = attr as InformationAttribute;                    if (null != informationAttribute)                    {                        //Console.WriteLine("Description of {0}:\n{1} {2}", field.Name,                        //    informationAttribute.Description, informationAttribute.DefaultValue);                        stringBuilder.AppendLine($"Description of { field.Name}:\n{informationAttribute.Description} {informationAttribute.DefaultValue}");
                        //给实例对应字段赋值                        if (field.FieldType == typeof(string))                        {                            newPerson.GetType().GetField(field.Name).SetValue(newPerson, informationAttribute.DefaultValue);                        }                        else if (field.FieldType == typeof(Int32))                        {                            newPerson.GetType().GetField(field.Name).SetValue(newPerson, Convert.ToInt32(informationAttribute.DefaultValue));                        }
                    }                }            }        }
        public FileStream FileReset(Stream fStream, string filename)        {            if (fStream != null)            {                fStream.Close();            }
            File.Delete(filename);            return new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);        }    }
    [DataContract(Name = "Person", Namespace = "http://www.person.com")]    public class Person    {        [DataMember()]        [Information(Description = "名称", DefaultValue = "本山")]        public string FirstName;        [DataMember]        [Information(Description = "性别", DefaultValue = "赵")]        public string LastName;        [DataMember()]        [Information(Description = "序号", DefaultValue = "1")]        public int ID;        [DataMember()]        public lesson lesson;        public Person(string newfName, string newLName, int newID, lesson lesson)        {            FirstName = newfName;            LastName = newLName;            ID = newID;            this.lesson = lesson;        }        public Person()        {
        }    }
    [DataContract()]    public class lesson    {        [DataMember()]        public string English { get; set; }        [DataMember()]        public string Chinese { get; set; }
        public override string ToString()        {            return $"[English] = [{English}], " +                $"[Chinese] = [{Chinese}], ";        }    }
    [AttributeUsage(AttributeTargets.All, AllowMultiple = true)]    public class InformationAttribute : Attribute    {        public string Name { get; set; }        public string Description { get; set; }        public string Unit { get; set; }        public string Range { get; set; }        public string AvailableValue { get; set; }        public string DefaultValue { get; set; }        public double Epsilon { get; set; }        public byte Precision { get; set; }        public string Parameter { get; set; }        public uint FixedSize { get; set; }        public NodeType NodeType { get; set; }    }
    //    // 摘要:    //     节点类型(仅用于Dictionary)    public enum NodeType    {        //        // 摘要:        //     The key of dict        Key = 0,        //        // 摘要:        //     The Value of dict        Value = 1    }}

要用DataContractSerializer,首先要引用库:

System.Runtime.Serialization.dll

需要序列化的类前需要用[DataContract]标注,需要序列化的字段需要用

[DataMember]标注,这里还定义了一个自定义属性InformationAttribute,它需要继承自Attribute,使用方法如下:

C# XML序列化和反序列化(DataContractSerializer)

这里通过反射Type type = typeof(Person);获取类型,通过GetCustomAttributes获取所有自定义特性,通过GetFields()获取当前 当前 System.Type 定义的字段,

给实例对应字段赋值

 if (field.FieldType == typeof(string))                        {                            newPerson.GetType().GetField(field.Name).SetValue(newPerson, informationAttribute.DefaultValue);                        }                        else if (field.FieldType == typeof(Int32))                        {                            newPerson.GetType().GetField(field.Name).SetValue(newPerson, Convert.ToInt32(informationAttribute.DefaultValue));                        }