XML和实体序列化和反序列化
近来的项目中用到了序列化就抽空学习了一下,拿出来给大家分享一下:
类为我们提供了自己对象串行化(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 "传入数据出错"; }
}
编译后运行,我们用刚才序列化出来的字符串贴出参数值位置就可以测试反序列化的方法,在此不再详述,有兴趣的童鞋可以把实例代码运行。