XML和實體序列化和反序列化

作者: 星空有我  來源: 博客園  發布時間: 2010-12-05 15:40  閱讀: 2994 次  推薦: 3   原文鏈接   [收藏]  

  近來的項目中用到了序列化就抽空學習了一下,拿出來給大家分享一下:

  類為我們提供了自己對象串行化(Serialize)和反串行化(Deserialize)的xml的方法,該類可以序列化的內容:
    公共類的公共讀寫字段或者屬性
    XmlElement對象
    XmlNode對象
    Dataset對象
    實現了Icollection 或IEnumerable的類

  該類在設計中有一個設計需求:
    需要被序列化的類要提供一個空參數的構造函數,否則運行時會出現異常

  在開發過程中可能會有很多地方要用到對象和XML相互轉化,在此提供一個通用的類,提供泛類型的支持。

 /// <summary>
    /// 序列化幫助類
    /// </summary>
    public class SHelper
    {
        /// <summary>
        /// 對象到XML-----泛類型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string SaveXmlFromObj<T>(T obj)
        {
            if (obj == null) return null;
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            MemoryStream stream = new MemoryStream();
            XmlTextWriter xtw = new XmlTextWriter(stream, Encoding.UTF8);
            xtw.Formatting = Formatting.Indented;
            try
            {
                serializer.Serialize(stream, obj);
            }
            catch { return null; }

            stream.Position = 0;
            string returnStr = string.Empty;
            using (StreamReader sr = new StreamReader(stream, Encoding.UTF8))
            {
                string line = "";
                while ((line = sr.ReadLine()) != null)
                {
                    returnStr += line;
                }
            }
            return returnStr;
        }

        /// <summary>
        /// XML到反序列化到對象----支持泛類型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="data"></param>
        /// <returns></returns>
        public static T LoadObjFromXML<T>(string data)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                using (StreamWriter sw = new StreamWriter(stream, Encoding.UTF8))
                {
                    sw.Write(data);
                    sw.Flush();
                    stream.Seek(0, SeekOrigin.Begin);
                    XmlSerializer serializer = new XmlSerializer(typeof(T));
                    try
                    {
                        return ((T)serializer.Deserialize(stream));
                    }
                    catch { return default(T); }

                }
            }
        }
    }

  該類提供兩方法,一個是從實體到返回XML字符串的方法,一個是把XML字符串裝成對象實體的方法。下面我們來看看這個類是怎么用的。

  首先建兩個類USer和Users,User測試一個實體的序列化和反序列化,USers測試一個List集合序列化和反序列化。注意這兩個類都標注了[Serializable]特性,并且提供了空參數的構造函數。

 
[Serializable]
public class User
{

public int ID { get; set; }
public string Name { get; set; }
public string Add { get; set; }
public int Age { get; set; }
public User()
{

this.ID = default(int);
this.Name = default(string);
this.Add = default(string);
this.Age = default(int);
}

}
 
[Serializable]
public class Users
{

public List<User> Datas { get; set; }
public Users()
{

this.Datas=new List<User>();
}
}

  下面我們建一個頁面Default.aspx,在這個頁面中我們測試序列化,提供兩個按鈕和兩個TextBox,來分別顯示單個實體的序列化和List集合的序列化。

 
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" Text="一個對象序列化"
onclick="Button1_Click" />
<br />
<asp:TextBox ID="TextBox1" runat="server" Width="100%" Height="200"></asp:TextBox><br />
<asp:Button ID="Button2" runat="server" Text="多個對象序列化"
onclick="Button2_Click" /><br />
<asp:TextBox ID="TextBox2" runat="server" Width="100%" Height="200"></asp:TextBox><br />
</div>
</form>

     后臺代碼的實現:

 
/// <summary>
/// 一個對象序列化
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Button1_Click(object sender, EventArgs e)
{
User user
= new User() { ID=1001,Name="小王",Add="北京",Age=21};
var str
= SHelper.SaveXmlFromObj<User>(user);
this.TextBox1.Text = str;
}


/// <summary>
/// 多個對象序列化
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Button2_Click(object sender, EventArgs e)
{
Users users
= new Users();
User user
= new User() { ID = 1001, Name = "小王", Add = "北京", Age = 21 };
users.Datas.Add(user);
users.Datas.Add(user);
users.Datas.Add(user);

var str
= SHelper.SaveXmlFromObj<Users>(users);
this.TextBox2.Text = str;
}

  序列化結果如下:

  單對象:

 
<?xml version="1.0"?><User xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <ID>1001</ID> <Name>小王</Name> <Add>北京</Add> <Age>21</Age></User>

  List集合

 
<?xml version="1.0"?><Users xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Datas> <User> <ID>1001</ID> <Name>小王</Name> <Add>北京</Add> <Age>21</Age> </User> <User> <ID>1001</ID> <Name>小王</Name> <Add>北京</Add> <Age>21</Age> </User> <User> <ID>1001</ID> <Name>小王</Name> <Add>北京</Add> <Age>21</Age> </User> </Datas></Users>

  下面我們來測試反序列化:

  首先建一個webservice,寫兩個測試方法:

 
[WebMethod]
public string GetObjFromXml(string data)
{
var obj
= SHelper.LoadObjFromXML<User>(data);
if (obj != null)
{
return obj.Name; }
else { return "傳入數據出錯"; }
}

[WebMethod]

public string GetObjsFromXml(string data)
{
var obj
= SHelper.LoadObjFromXML<Users>(data);
if (obj != null)
{
string returnstr
= "";
foreach (User user in obj.Datas)
{
returnstr
+= user.Name + "\n";
}

return returnstr;
}

else { return "傳入數據出錯"; }
}

  編譯后運行,我們用剛才序列化出來的字符串貼出參數值位置就可以測試反序列化的方法,在此不再詳述,有興趣的童鞋可以把實例代碼運行。

3
0
 
標簽:XML 序列化
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()