C# 序列化与反序列化Serialization之Json Xml Binary Soap JavaScript序列化

所谓的序列化其实就是把一个内存中的对象信息转化成一个可以持久化保存的形式,方便保存数据库和文件或着用于传输,

序列化的主要作用是不同平台之间进行通信与信息的传递保存等,常用的有序列化有Json Xml Binary Soap JavaScript序列化等,当然我们也可以使用第三方的序列化类库,第三方的序列化类库可以参照网上的,这里不再赘述,

本文主要介绍Json Xml Binary Soap JavaScript等6种序列化的方法,

添加引用以下类库

using System.Runtime.Serialization.Json;//DataContractJsonSerializer序列化
using System.Xml.Serialization;//XmlSerializer序列化
using System.Runtime.Serialization.Formatters.Binary;//BinarySerializer序列化
using System.Runtime.Serialization.Formatters.Soap;//SoapSerializer序列化
using System.Web.Script.Serialization;//JavaScriptSerializer序列化

代码如下:

using System;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Json;//DataContractJsonSerializer序列化
using System.Xml.Serialization;//XmlSerializer序列化
using System.Runtime.Serialization.Formatters.Binary;//BinarySerializer序列化
using System.Runtime.Serialization.Formatters.Soap;//SoapSerializer序列化
using System.Web.Script.Serialization;//JavaScriptSerializer序列化

namespace SupremeConsole
{
    /// <summary>
    /// 序列化单例对象
    /// </summary>
    public class SerializeManager : SingleManager<SerializeManager>
    {
        public SerializeManager()
        {
            Initialize();
        }

        public override void Initialize()
        {
            base.Initialize();
        }

        /// <summary>
        /// DataContractJson泛型序列化
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="t">泛型对象</param>
        /// <returns>泛型对象序列化的字符串</returns>
        public string DataContractJsonSerialize<T>(T t) where T : class
        {
            string s = null;
            try
            {
                using MemoryStream ms = new MemoryStream();
                DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(T));
                dcjs.WriteObject(ms, t);
                s = Encoding.UTF8.GetString(ms.ToArray());
            }
            catch (Exception ex)
            {
                Program.Log.Error($"DataContractJson泛型序列化错误信息:{ex.ToString()}");
            }
            return s;
        }

        /// <summary>
        /// DataContractJson泛型序列化
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="t">泛型对象</param>
        /// <param name="path">保存的路径</param>
        public void DataContractJsonSerialize<T>(T t, string path) where T : class
        {
            try
            {
                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "test.txt");
                using FileStream fs = new FileStream(path, FileMode.OpenOrCreate);
                DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(T));
                dcjs.WriteObject(fs, t);
            }
            catch (Exception ex)
            {
                Program.Log.Error($"DataContractJson泛型序列化错误信息:{ex.ToString()}");
            }
        }

        /// <summary>
        /// DataContractJson泛型的反序列化
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="json">反序列化的序列化文件路径</param>
        /// <returns>泛型对象</returns>
        public T DataContractJsonDeserializeJson<T>(string json) where T : class
        {
            T t = null;
            try
            {
                using MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json));
                DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(T));
                if (dcjs.ReadObject(ms) is T a)
                {
                    t = a;
                }
            }
            catch (Exception ex)
            {
                Program.Log.Error($"DataContractJson泛型反序列化错误信息:{ex.ToString()}");
            }
            return t;
        }

        /// <summary>
        /// DataContractJson泛型的反序列化
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="json">反序列化的序列化文件路径</param>
        /// <returns>泛型对象</returns>
        public T DataContractJsonDeserialize<T>(string path) where T : class
        {
            T t = null;
            try
            {
                using MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(File.ReadAllText(path)));
                DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(T));
                if (dcjs.ReadObject(ms) is T a)
                {
                    t = a;
                }
            }
            catch (Exception ex)
            {
                Program.Log.Error($"DataContractJson泛型反序列化错误信息:{ex.ToString()}");
            }
            return t;
        }

        /// <summary>
        /// Xml泛型序列化
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="t">泛型对象</param>
        /// <returns>泛型对象序列化的字符串</returns>
        public string XmlSerialize<T>(T t) where T : class
        {
            string s = null;
            try
            {
                using MemoryStream ms = new MemoryStream();
                XmlSerializer xs = new XmlSerializer(typeof(T));
                xs.Serialize(ms, t);
                s = Encoding.UTF8.GetString(ms.ToArray());
            }
            catch (Exception ex)
            {
                Program.Log.Error($"Xml泛型序列化错误信息:{ex.ToString()}");
            }
            return s;
        }

        /// <summary>
        /// Xml泛型序列化
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="t">泛型对象</param>
        /// <param name="path">保存的路径</param>
        public void XmlSerialize<T>(T t, string path) where T : class
        {
            try
            {
                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "test.txt");
                using FileStream fs = new FileStream(path, FileMode.OpenOrCreate);
                XmlSerializer xs = new XmlSerializer(typeof(T));
                xs.Serialize(fs, t);
            }
            catch (Exception ex)
            {
                Program.Log.Error($"Xml泛型序列化错误信息:{ex.ToString()}");
            }
        }

        /// <summary>
        /// Xml泛型的反序列化
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="path">反序列化的序列化文件路径</param>
        /// <returns>泛型对象</returns>
        public T XmlDeserialize<T>(string path) where T : class
        {
            T t = null;
            try
            {
                using MemoryStream ms = new MemoryStream(File.ReadAllBytes(path));
                XmlSerializer xs = new XmlSerializer(typeof(T));
                if (xs.Deserialize(ms) is T a)
                {
                    t = a;
                }
            }
            catch (Exception ex)
            {
                Program.Log.Error($"Xml泛型的反序列化错误信息:{ex.ToString()}");
            }
            return t;
        }

        /// <summary>
        /// Binary泛型序列化
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="t">泛型对象</param>
        /// <returns>泛型对象序列化的字符串</returns>
        public string BinarySerialize<T>(T t) where T : class
        {
            string s = null;
            try
            {
                using MemoryStream ms = new MemoryStream();
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(ms, t);
                s = Encoding.UTF8.GetString(ms.ToArray());
            }
            catch (Exception ex)
            {
                Program.Log.Error($"Binary泛型序列化错误信息:{ex.ToString()}");
            }
            return s;
        }

        /// <summary>
        /// Binary泛型序列化
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="t">泛型对象</param>
        /// <param name="path">保存的路径</param>
        public void BinarySerialize<T>(T t, string path) where T : class
        {
            try
            {
                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "test.txt");
                using FileStream fs = new FileStream(path, FileMode.OpenOrCreate);
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(fs, t);
            }
            catch (Exception ex)
            {
                Program.Log.Error($"Binary泛型序列化错误信息:{ex.ToString()}");
            }
        }

        /// <summary>
        /// Binary泛型的反序列化
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="path">反序列化的序列化文件路径</param>
        /// <returns>泛型对象</returns>
        public T BinaryDeserialize<T>(string path) where T : class
        {
            T t = null;
            try
            {
                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "test.txt");
                using MemoryStream fs = new MemoryStream(File.ReadAllBytes(path));
                BinaryFormatter bf = new BinaryFormatter();
                if (bf.Deserialize(fs) is T a)
                {
                    t = a;
                }
            }
            catch (Exception ex)
            {
                Program.Log.Error($"Binary泛型的反序列化错误信息:{ex.ToString()}");
            }
            return t;
        }

        /// <summary>
        /// Soap泛型序列化
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="t">泛型对象</param>
        /// <returns>泛型对象序列化的字符串</returns>
        public string SoapSerialize<T>(T t) where T : class
        {
            string s = null;
            try
            {
                using MemoryStream ms = new MemoryStream();
                SoapFormatter sf = new SoapFormatter();
                sf.Serialize(ms, t);
                s = Encoding.UTF8.GetString(ms.ToArray());
            }
            catch (Exception ex)
            {
                Program.Log.Error($"Soap泛型序列化错误信息:{ex.ToString()}");
            }
            return s;
        }

        /// <summary>
        ///Soap泛型序列化
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="t">泛型对象</param>
        /// <param name="path">保存的路径</param>
        public void SoapSerialize<T>(T t, string path) where T : class
        {
            try
            {
                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "test.txt");
                using FileStream fs = new FileStream(path, FileMode.OpenOrCreate);
                SoapFormatter sf = new SoapFormatter();
                sf.Serialize(fs, t);
            }
            catch (Exception ex)
            {
                Program.Log.Error($"Soap泛型序列化错误信息:{ex.ToString()}");
            }
        }

        /// <summary>
        /// Soap泛型的反序列化
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="path">反序列化的序列化文件路径</param>
        /// <returns>泛型对象</returns>
        public T SoapDeserialize<T>(string path) where T : class
        {
            T t = null;
            try
            {
                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "test.txt");
                using MemoryStream fs = new MemoryStream(File.ReadAllBytes(path));
                SoapFormatter sf = new SoapFormatter();
                if (sf.Deserialize(fs) is T a)
                {
                    t = a;
                }
            }
            catch (Exception ex)
            {
                Program.Log.Error($"Soap泛型的反序列化错误信息:{ex.ToString()}");
            }
            return t;
        }


        /// <summary>
        /// JavaScript泛型序列化
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="t">泛型对象</param>
        /// <returns>泛型对象序列化的字符串</returns>
        public string JavaScriptSerialize<T>(T t) where T : class
        {
            string s = null;
            try
            {
                JavaScriptSerializer jss = new JavaScriptSerializer();
                s = jss.Serialize(t);
            }
            catch (Exception ex)
            {
                Program.Log.Error($"JavaScript泛型序列化错误信息:{ex.ToString()}");
            }
            return s;
        }

        /// <summary>
        ///JavaScript泛型序列化
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="t">泛型对象</param>
        /// <param name="path">保存的路径</param>
        public void JavaScriptSerialize<T>(T t, string path) where T : class
        {
            try
            {
                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "test.txt");
                using FileStream fs = new FileStream(path, FileMode.OpenOrCreate);
                using StreamWriter sw = new StreamWriter(fs);
                StringBuilder sb = new StringBuilder();
                JavaScriptSerializer jss = new JavaScriptSerializer();
                jss.Serialize(t, sb);
                sw.WriteLine(sb.ToString());
            }
            catch (Exception ex)
            {
                Program.Log.Error($"JavaScript泛型序列化错误信息:{ex.ToString()}");
            }
        }

        /// <summary>
        /// JavaScript泛型的反序列化
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="path">反序列化的序列化文件路径</param>
        /// <returns>泛型对象</returns>
        public T JavaScriptDeserialize<T>(string path) where T : class
        {
            T t = null;
            try
            {
                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "test.txt");
                string input = Encoding.UTF8.GetString(File.ReadAllBytes(path));
                JavaScriptSerializer jss = new JavaScriptSerializer();
                if (jss.Deserialize<T>(input) is T a)
                {
                    t = a;
                }
            }
            catch (Exception ex)
            {
                Program.Log.Error($"JavaScript泛型的反序列化错误信息:{ex.ToString()}");
            }
            return t;
        }
    }
}

控制台程序主方法Main测试调用方式如下:

        static void Main(string[] args)
        {
            #region MyRegion
            try
            {
                TestClass testClass = new TestClass { Id = 1, Name = "张三", Age = 10, Address = "上海浦东新区2弄5汤", Sex = "" };
                #region DataContractJsonSerialize 要序列化的对象可以不添加SerializableAttribute属性,[Serializable]
                //string s = SerializeManager.Instance.DataContractJsonSerialize<TestClass>(testClass);//序列化
                //Console.ForegroundColor = ConsoleColor.Green;
                //Console.WriteLine("测试序列化成功。。。");
                //Console.WriteLine($"测试序列化结果:{s}");

                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "序列化123.txt");//序列化
                //SerializeManager.Instance.DataContractJsonSerialize<TestClass>(testClass, path);

                //string json = "{"Address":"中国南京","Age":10,"Id":1,"Name":"张三","Sex":"男"}";
                //TestClass test = SerializeManager.Instance.DataContractJsonDeserializeJson<TestClass>(json);//反序列化
                //if (test != null)
                //{
                //    Console.WriteLine($"测试序列化结果:{test.ToString()}");
                //}

                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "序列化123.txt");
                //TestClass test = SerializeManager.Instance.DataContractJsonDeserialize<TestClass>(path);//反序列化
                //if (test != null)
                //{
                //    Console.WriteLine($"测试序列化结果:{test.ToString()}");
                //}               
                #endregion

                #region XmlSerialize 要序列化的对象可以不添加SerializableAttribute属性,[Serializable]
                //string s = SerializeManager.Instance.XmlSerialize<TestClass>(testClass);//序列化
                //Console.ForegroundColor = ConsoleColor.Green;
                //Console.WriteLine("测试序列化成功。。。");
                //Console.WriteLine($"测试序列化结果:
{s}");

                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "序列化.txt");//序列化
                //SerializeManager.Instance.XmlSerialize<TestClass>(testClass, path);

                //备用
                //string json = "{"Address":"中国南京","Age":10,"Id":1,"Name":"张三","Sex":"男"}";
                //TestClass test = SerializeManager.Instance.DataContractJsonDeserializeJson<TestClass>(json);//反序列化
                //if (test != null)
                //{
                //    Console.WriteLine($"测试序列化结果:{test.ToString()}");
                //}

                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "序列化.txt");
                //TestClass test = SerializeManager.Instance.XmlDeserialize<TestClass>(path);//反序列化
                //if (test != null)
                //{
                //    Console.WriteLine($"测试序列化结果:{test.ToString()}");
                //} 
                #endregion

                TestClass1 testClass1 = new TestClass1 { Id = 11, Name = "张三11111", Age = 10, Address = "12123上海浦东新区2弄5汤1111", Sex = "" };
                #region BinarySerialize 必须添可序列化属性,即要序列化的对象必须添加SerializableAttribute属性,[Serializable]
                //string s = SerializeManager.Instance.BinarySerialize<TestClass1>(testClass1);//序列化
                //Console.ForegroundColor = ConsoleColor.Green;
                //Console.WriteLine("测试序列化成功。。。");
                //Console.WriteLine($"测试序列化结果:
{s}");

                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "序列化11111.txt");//序列化
                //SerializeManager.Instance.BinarySerialize<TestClass1>(testClass1, path);

                //备用
                //string json = "{"Address":"中国南京","Age":10,"Id":1,"Name":"张三","Sex":"男"}";
                //TestClass test = SerializeManager.Instance.DataContractJsonDeserializeJson<TestClass>(json);//反序列化
                //if (test != null)
                //{
                //    Console.WriteLine($"测试序列化结果:{test.ToString()}");
                //}

                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "序列化11111.txt");
                //TestClass1 test = SerializeManager.Instance.BinaryDeserialize<TestClass1>(path);//反序列化
                //if (test != null)
                //{
                //    Console.WriteLine($"测试序列化结果:{test.ToString()}");
                //}
                #endregion

                #region SoapSerialize 必须添可序列化属性,即要序列化的对象必须添加SerializableAttribute属性,[Serializable]
                //string s = SerializeManager.Instance.SoapSerialize<TestClass1>(testClass1);//序列化
                //Console.ForegroundColor = ConsoleColor.Green;
                //Console.WriteLine("测试序列化成功。。。");
                //Console.WriteLine($"测试序列化结果:
{s}");

                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "序列化2222.txt");//序列化
                //SerializeManager.Instance.SoapSerialize<TestClass1>(testClass1, path);

                //备用
                //string json = "{"Address":"中国南京","Age":10,"Id":1,"Name":"张三","Sex":"男"}";
                //TestClass test = SerializeManager.Instance.DataContractJsonDeserializeJson<TestClass>(json);//反序列化
                //if (test != null)
                //{
                //    Console.WriteLine($"测试序列化结果:{test.ToString()}");
                //}

                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "序列化2222.txt");
                //TestClass1 test = SerializeManager.Instance.SoapDeserialize<TestClass1>(path);//反序列化
                //if (test != null)
                //{
                //    Console.WriteLine($"测试序列化结果:{test.ToString()}");
                //}
                #endregion

                #region JavaScriptSerialize 要序列化的对象可以不添加SerializableAttribute属性,[Serializable]
                //string s = SerializeManager.Instance.JavaScriptSerialize<TestClass1>(testClass1);//序列化
                //Console.ForegroundColor = ConsoleColor.Green;
                //Console.WriteLine("测试序列化成功。。。");
                //Console.WriteLine($"测试序列化结果:
{s}");

                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "序列化66666.txt");//序列化
                //SerializeManager.Instance.JavaScriptSerialize<TestClass1>(testClass1, path);

                //备用
                //string json = "{"Address":"中国南京","Age":10,"Id":1,"Name":"张三","Sex":"男"}";
                //TestClass test = SerializeManager.Instance.DataContractJsonDeserializeJson<TestClass>(json);//反序列化
                //if (test != null)
                //{
                //    Console.WriteLine($"测试序列化结果:{test.ToString()}");
                //}

                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "序列化66666.txt");
                //TestClass1 test = SerializeManager.Instance.JavaScriptDeserialize<TestClass1>(path);//反序列化
                //if (test != null)
                //{
                //    Console.WriteLine($"测试序列化结果:{test.ToString()}");
                //}
                #endregion

                Console.WriteLine("测试序列化成功。。。");
            }
            catch (Exception ex)
            {
                Log.Error($"测试序列化出错,原因:{ex.ToString()}");
                throw;
            }

            #endregion
          
            Console.ReadLine();
        }

使用的类TestClass和TestClass1,类TestClass和TestClass1主要是区分是否添加可序列化属性标记,TestClass主要是测试XmlSerializer(xml序列化)和DatacontractJsonSerializer(json序列化),可以不添加可序列化标记 [Serializable],TestClass1主要是测试Binary和Soap JavaScript序列化,但Binary和Soap JavaScript序列化TestClass1时,必须添加TestClass1的可序列化标记 [Serializable],否则,BinarySerialize,SoapSerialize序列化TestClass1的时候会报,提示未标记可序列化

TestClass类

namespace SupremeConsole
{
    /// <summary>
    ///  测试类,该类必未标记为可序列化,DataContractJsonSerialize,XmlSerialize可以正常序列化
    /// </summary>
    public class TestClass
    {
        /// <summary>
        /// 编号
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        /// 姓名
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 年龄
        /// </summary>
        public int Age { get; set; }

        /// <summary>
        /// 地址
        /// </summary>
        public string Address { get; set; }

        /// <summary>
        /// 性别
        /// </summary>
        public string Sex { get; set; }

        public override string ToString()
        {
            //return string.Format("编号:{0},姓名:{1},年龄:{2},地址:{3},性别:{4}", Id, Name, Age, Address, Sex);
            return $"编号:{Id},姓名:{Name},年龄:{Age},地址:{Address},性别:{Sex}";
        }
    }
}

 

TestClass1类

using System;
using System.Runtime.Serialization;

namespace SupremeConsole
{
    /// <summary>
    /// 测试类1,该类必须标记可序列化,否则,BinarySerialize,SoapSerialize序列化的时候会报,未标记可序列化
    /// </summary>
    [Serializable]
    [DataContract]
    public class TestClass1
    {
        /// <summary>
        /// 编号
        /// </summary>
       
        public int Id { get; set; }

        /// <summary>
        /// 姓名
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 年龄
        /// </summary>
        public int Age { get; set; }

        /// <summary>
        /// 地址
        /// </summary>
        public string Address { get; set; }

        /// <summary>
        /// 性别
        /// </summary>
        public string Sex { get; set; }

        public override string ToString()
        {
            //return string.Format("编号:{0},姓名:{1},年龄:{2},地址:{3},性别:{4}", Id, Name, Age, Address, Sex);
            return $"编号:{Id},姓名:{Name},年龄:{Age},地址:{Address},性别:{Sex}";
        }
    }
}