【C#.Net】XML與JSON之物件序列/反序列化

  • 2828
  • 0
  • 2018-12-05

說明物件(object)如何序列化(serialize)轉成 XML 與 JSON 格式之字符串(string),並反序列化(deserialize)轉回成物件(object)作使用。

XML 與 JSON 序列化 / 反序列化靜態類別


    public static class JObjectSerializer
    {
        /// <summary>
        /// XML 序列/反序列化物件類別
        /// </summary>
        public static class XML
        {
            /// <summary>
            /// 將物件序列化成XML格式字串
            /// </summary>
            /// <typeparam name="T">物件型別</typeparam>
            /// <param name="obj">物件</param>
            /// <returns>XML格式字串</returns>
            public static string Serialize<T>(T obj) where T : class
            {
                XmlSerializer serializer = new XmlSerializer(obj.GetType());
                var stringWriter = new StringWriter();
                using (var writer = XmlWriter.Create(stringWriter))
                {
                    serializer.Serialize(writer, obj);
                    return IndentXMLString(stringWriter.ToString());
                }
            }

            /// <summary>
            /// 將XML格式字串反序列化成物件
            /// </summary>
            /// <typeparam name="T">物件型別</typeparam>
            /// <param name="xmlString">XML格式字串</param>
            /// <returns>反序列化後的物件</returns>
            public static T Deserialize<T>(string xmlString) where T : class
            {
                XmlSerializer deserializer = new XmlSerializer(typeof(T));
                using (TextReader reader = new StringReader(xmlString))
                {
                    object deserializationObj = deserializer.Deserialize(reader);
                    return deserializationObj as T;
                };
            }

            /// <summary>
            /// 格式化 XML 字串 (方便人員閱讀)
            /// 【 XML Formatter Link 】 - 將 XML 內容格式化排列整齊,方便閱讀的網站。
            /// Formats a XML string/file with your desired indentation level. 
            /// The formatting rules are not configurable but it uses a per-element indentation pattern giving the best readability. 
            /// https://www.freeformatter.com/xml-formatter.html
            /// </summary>
            /// <param name="XML">格式化前的 XML 字串</param>
            /// <returns>格式化後的 XML 字串</returns>
            public static String IndentXMLString(String XML)
            {
                String Result = "";

                MemoryStream mStream = new MemoryStream();
                XmlTextWriter writer = new XmlTextWriter(mStream, Encoding.Unicode);
                XmlDocument document = new XmlDocument();

                try
                {
                    // Load the XmlDocument with the XML.
                    document.LoadXml(XML);

                    writer.Formatting = System.Xml.Formatting.Indented;

                    // Write the XML into a formatting XmlTextWriter
                    document.WriteContentTo(writer);
                    writer.Flush();
                    mStream.Flush();

                    // Have to rewind the MemoryStream in order to read
                    // its contents.
                    mStream.Position = 0;

                    // Read MemoryStream contents into a StreamReader.
                    StreamReader sReader = new StreamReader(mStream);

                    // Extract the text from the StreamReader.
                    String FormattedXML = sReader.ReadToEnd();

                    Result = FormattedXML;
                }
                catch (XmlException)
                {
                }

                mStream.Close();
                writer.Close();

                return Result;
            }
        }

        /// <summary>
        /// JSON 序列/反序列化物件類別
        /// </summary>
        public static class JSON
        {
            /// <summary>
            /// 將物件序列化成JSON格式字串
            /// </summary>
            /// <typeparam name="T">物件型別</typeparam>
            /// <param name="obj">物件</param>
            /// <returns>XML格式字串</returns>
            public static string Serialize<T>(T obj) where T : class
            {
                string json_data = JsonConvert.SerializeObject(obj);//存放序列後的文字
                return IndentJsonString(json_data);
            }

            /// <summary>
            /// 將JSON格式字串反序列化成物件
            /// </summary>
            /// <typeparam name="T">物件型別</typeparam>
            /// <param name="xmlString">XML格式字串</param>
            /// <returns>反序列化後的物件</returns>
            public static T Deserialize<T>(string jsonString) where T : class
            {
                return JsonConvert.DeserializeObject<T>(jsonString);
            }


            /// <summary>
            /// 格式化JSON字符串
            /// </summary>
            /// <param name="str">格式化前的 JSON 字串</param>
            /// <returns>格式化後的 JSON 字串</returns>
            public static string IndentJsonString(string str)
            {
                string sRet = str;
                JsonSerializer serializer = new JsonSerializer();
                using (TextReader tr = new StringReader(str))
                {
                    using (JsonTextReader jtr = new JsonTextReader(tr))
                    {
                        object obj = serializer.Deserialize(jtr);
                        if (obj != null)
                        {
                            using (StringWriter textWriter = new StringWriter())
                            {
                                using (JsonTextWriter jsonWriter = new JsonTextWriter(textWriter)
                                {
                                    Formatting = Newtonsoft.Json.Formatting.Indented,
                                    Indentation = 4,
                                    IndentChar = ' '
                                })
                                {
                                    serializer.Serialize(jsonWriter, obj);
                                    sRet = textWriter.ToString();
                                }
                            }
                        }
                    }
                }
                return sRet;
            }

        }
    }

測試用樣本資料類別


    public class PC : IDisposable
    {
        public string Belong2 { get; set; }
        public DateTime DatePurchased { get; set; }
        public Hardware Hardware { get; set; }
        public Software Software { get; set; }

        public PC()
        {
            Hardware = new Hardware();
            Software = new Software();
        }

        public void Dispose()
        {
            Hardware.Clear();
            Software.Clear();
        }
    }

    public class Hardware
    {
        public string CPU { get; set; }
        public int RAMSize { get; set; }
        public List<Harddisk> HardDisks { get; set; }

        public Hardware()
        { 
            HardDisks = new List<Harddisk>();
        }

        public void Clear()
        {
            HardDisks.Clear();
            HardDisks.TrimExcess();
        }
    }

    public class Harddisk
    {
        public string Brand { get; set; }
        public int Size { get; set; }
        public string Type { get; set; }
    }

    public class Software
    {
        public string OS { get; set; }
        public List<App> Apps { get; set; }

        public Software()
        {
            Apps = new List<App>();
        }

        public void Clear()
        {
            Apps.Clear();
            Apps.TrimExcess();
        }
    }

    public class App
    {
        public string Name { get; set; }
        public string Version { get; set; }
    }

測試範例


            using(PC pc = new PC())
            {
                pc.Belong2 = "Johnny";
                pc.DatePurchased = DateTime.Now;
                pc.Hardware.CPU = "Intel Core i5-3470 @ 3.20GHz";
                pc.Hardware.RAMSize = 8;
                pc.Hardware.HardDisks.Add(new Harddisk(){Brand = "Seagate", Size = 500});
                pc.Hardware.HardDisks.Add(new Harddisk(){Brand = "Intel", Size = 128, Type = "SSD"});
                pc.Software.OS = "Windows 7 Professional 64-bit Service Pack 1";
                pc.Software.Apps.Add(new App(){Name = "Office 2013"});
                pc.Software.Apps.Add(new App(){Name = "Visual Studio 2013", Version = "12.0.30110.00 Update 1"});

                //將 PC object 轉為 XML string
                rtbXML.Text = JObjectSerializer.XML.Serialize<PC>(pc);
                //將 PC object 轉為 JSON string
                rtbJSON.Text = JObjectSerializer.JSON.Serialize<PC>(pc);

                //將 XML string 轉為 PC object
                PC pc_xml = JObjectSerializer.XML.Deserialize<PC>(rtbXML.Text);
                //將 JSON string 轉為 PC object
                PC pc_json = JObjectSerializer.JSON.Deserialize<PC>(rtbJSON.Text);

            }

補充

Json.Net 套件安裝可參考這篇說明:https://dotblogs.com.tw/jwpl102216/2018/01/06/092426