天天看點

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 = ;              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 ( != 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 ( != 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 ( != 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 != )              {              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));              }           

繼續閱讀