標籤:exception block 背景顏色 space 欄位 輸出 問題 orb attr
今天來接著寫這個系列的文章,這一篇主要是用來介紹關於C#中的XML序列化的問題,這個相信大家一定會經常使用它,特別是在WPF中,有時候我們需要將我們背景資料儲存在資料庫中,從而在軟體下一次啟動的時候能夠自動去載入這些資料,由於我們的這些Model中欄位眾多,如果單獨進行儲存那是不太現實的,這個時候將這些欄位序列化成xml字串並儲存在資料庫中就是一個不錯的選擇,當我們需要這些資料的時候我們也可以反過來將其序列化為一些欄位,最終達到我們的效果,首先我們來看看是如何?的?
public class XMLUtil { /// <summary> /// XML & Datacontract Serialize & Deserialize Helper /// </summary> /// <typeparam name="T"></typeparam> /// <param name="serialObject"></param> /// <returns></returns> public static string Serializer<T>(T serialObject) where T : class { try { XmlSerializer ser = new XmlSerializer(typeof(T)); System.IO.MemoryStream mem = new MemoryStream(); XmlTextWriter writer = new XmlTextWriter(mem, Encoding.UTF8); ser.Serialize(writer, serialObject); writer.Close(); return Encoding.UTF8.GetString(mem.ToArray()); } catch (Exception ex) { return null; } } public static T Deserialize<T>(string str) where T : class { try { XmlSerializer mySerializer = new XmlSerializer(typeof(T)); StreamReader mem2 = new StreamReader( new MemoryStream(System.Text.Encoding.UTF8.GetBytes(str)), System.Text.Encoding.UTF8); return (T)mySerializer.Deserialize(mem2); } catch (Exception) { return null; } } }
微軟為我們提供的XmlSerializer這個類就為我們提供了這個可能,在序列化的過程中我們需要注意下面的情況,所有的屬性必須是可序列化的對象,像BitmapImage、SolidColorBrush等這些對象都是不能夠進行序列化的對象,如果用上面的方法進行序列化時將返回null,正確的方式是在這些欄位上面加上[XmlIgnore]說明,從而在進行序列化時候跳過這些對象,就像下面的方式。
/// <summary> ///背景顏色 /// </summary> private SolidColorBrush _BackgroundColor; [XmlIgnore] public SolidColorBrush BackgroundColor { get { return _BackgroundColor; } set { if (value != _BackgroundColor) { _BackgroundColor = value; OnPropertyChanged("BackgroundColor"); } } }
那麼像上面的這個SolidColorBrush對象該怎樣去進行序列化呢,這裡我們選擇將使用中色彩的ARGB值儲存在一個byte數組中,從而在還原序列化的時候通過Color.FromArgb的方式進行還原,就像下面的方式。
byte[] colorByte=savedModel.ConfigurationBaseModel.BackgroundColorArgb; Color backColor=Color.FromArgb(colorByte[0],colorByte[1],colorByte[2],colorByte[3]); sourceBaseModel.BackgroundColor = new SolidColorBrush(backColor);
那麼這個對象在進行序列化的時候該怎麼進行儲存呢?同樣的原理我們可以通過下面的方式。
/// <summary> ///背景顏色 /// </summary> private SolidColorBrush _BackgroundColor; [XmlIgnore] public SolidColorBrush BackgroundColor { get { return _BackgroundColor; } set { if (value != _BackgroundColor) { _BackgroundColor = value; OnPropertyChanged("BackgroundColor"); } } } /// <summary> ///背景顏色ARGB /// </summary> private byte[] _BackgroundColorArgb=new byte[4]; [XmlArray("argb"),XmlArrayItem("value")] public byte[] BackgroundColorArgb { get { if (null != _BackgroundColor) { Color color = _BackgroundColor.Color; _BackgroundColorArgb[0] = color.A; _BackgroundColorArgb[1] = color.R; _BackgroundColorArgb[2] = color.G; _BackgroundColorArgb[3] = color.B; } return _BackgroundColorArgb; } set { if (value != _BackgroundColorArgb) { _BackgroundColorArgb = value; OnPropertyChanged("BackgroundColorArgb"); } } }
這裡在實際的使用中發現,就像byte數組必須通過[XmlArray("argb"),XmlArrayItem("value")] 這類型的標識來將其分類,在將其序列化完畢以後,我們可以看看這個BackgroundColorArgb欄位最終是通過怎樣的方式來儲存的?
在進行還原序列化的時候會將這個argb和value還原序列化為一個byte數組。
除了這些特例意外,有時候經常需要將一些對象的數組進行序列化,那麼原理是什麼呢?這裡我借用別人的一個例子來進行相關的說明。
對象數組的Xml序列化:
數組的Xml序列化需要使用XmlArrayAttribute和XmlArrayItemAttribute;XmlArrayAttribute指定數組元素的Xml節點名,XmlArrayItemAttribute指定數組元素的Xml節點名。
如下程式碼範例:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Xml.Serialization; namespace UseXmlSerialization{ class Program { static void Main(string[] args) { //聲明一個貓咪對象 var cWhite = new Cat { Color = "White", Speed = 10, Saying = "White or black, so long as the cat can catch mice, it is a good cat" }; var cBlack = new Cat { Color = "Black", Speed = 10, Saying = "White or black, so long as the cat can catch mice, it is a good cat" }; CatCollection cc = new CatCollection { Cats = new Cat[] { cWhite,cBlack} }; //序列化這個對象 XmlSerializer serializer = new XmlSerializer(typeof(CatCollection)); //將對象序列化輸出到控制台 serializer.Serialize(Console.Out, cc); Console.Read(); } } [XmlRoot("cats")] public class CatCollection { [XmlArray("items"),XmlArrayItem("item")] public Cat[] Cats { get; set; } } [XmlRoot("cat")] public class Cat { //定義Color屬性的序列化為cat節點的屬性 [XmlAttribute("color")] public string Color { get; set; } //要求不序列化Speed屬性 [XmlIgnore] public int Speed { get; set; } //設定Saying屬性序列化為Xml子項目 [XmlElement("saying")] public string Saying { get; set; } }}
最終獲得的結果是:
<?xml version="1.0" encoding="gb2312"?><cats xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <items> <item color="White"> <saying>White or black, so long as the cat can catch mice, it is a good cat</saying> </item> <item color="Black"> <saying>White or black, so long as the cat can catch mice, it is a good cat</saying> </item> </items></cats>
通過這個例子讓我們去初步瞭解XML序列化的相關知識。
C# 中那些常用的工具類(Utility Class)(三)