本节将介绍如何使用ServiceStack.Text 来完成高性能序列化和反序列化操作。

在上章构建高性能ASP.NET应用的几点建议 中提到使用高性能类库,有关于JSON序列化的讨论。

在诊断web站点的性能问题时发现了代码中的一个热点问题:来自第三方web服务的JSON信息必须要被反序列化多次。那些Json信息是由Newtonsoft.Json反序列化的,并且证明了Newtonsoft.Json在反序列化时不是最快的类库,然后我们使用了一个更快的类库(如ServiceStack)替代了Json.Net,并获得了更好的结果。

如果我们在挑选了Json.Net作为序列化类库的早期阶段就完成了负载测试,那么我们就会更早地发现性能问题,我们就不必再代码中做这么多的修改了,也不必再次完整地重新测试了。

首先,我们有下边两个类,一个是职员(Staff)类,一个是联系方式(Contact)类:

public class Staff

{

public long ID { get; set; }

public string Name { get; set; }

public int Age { get; set; }

}

public class Contact

{

public long StaffID { get; set; }

public string Email { get; set; }

}

纯手工序列化方法:

var result = "[";

foreach (var staff in listStaff)

{

result += "{\"ID\":\"" + staff.ID + "\",\"Name\":\"" + staff.Name + "\"},";

}

result = result.Substring(0, result.Length - 1);

result += "]";

得到json如:

[

{

"ID": "2",

"Name": "小李"

},

{

"ID": "3",

"Name": "小王"

}

]

下边看看使用 ServiceStack.Text 来序列化 json。

我们需要下载 ServiceStack.Text.dll,将它引用到我们的项目中,并引用 ServiceStack.Text 命名空间。下边先看看单个类对象的序列化:

Staff staff = new Staff() { ID = 1, Name = "xiaozhao" };

var result = staff.ToJson();

得到:

{

"ID": 1,

"Name": "xiaozhao",

"Age": 0

}

如果我们在输出中并不打算使用 Age 属性,但这里却输出了 Age,为解决这个问题,我们有下边方法。

1.使用 JsonObject 类,它继承自Dictionary,使得我们可以如下来输出我们想要的属性。

Staff staff = new Staff() { ID = 1, Name = "xiaozhao" };

JsonObject json = new JsonObject();

json.Add("ID", staff.ID.ToString());

json.Add("Name", staff.Name);

var result = json.ToJson();

得到:

{

"ID": 1,

"Name": "xiaozhao"

}

2.在项目中添加 System.Runtime.Serialization ,并引用命名空间 System.Runtime.Serialization。

我们可以在属性上边指明要序列化的属性,如下:

[DataContract]

public class Staff

{

[DataMember]

public long ID { get; set; }

[DataMember]

public string Name { get; set; }

public int Age { get; set; }

}

或者:

public class Staff

{

public long ID { get; set; }

public string Name { get; set; }

[IgnoreDataMember]

public int Age { get; set; }

}

这样下边的代码输出的结果就变得和[结果一]相同了

最后,我们看下类对象集合的序列化,我们添加职员的联系方式如下:

List listContact = new List();

listContact.Add(new Contact() { StaffID = 3, Email = "xiaowang@163.com" });

listContact.Add(new Contact() { StaffID = 4, Email = "xiaoli@163.com" });

每个职员可能对应一个联系方式,这里要考虑有的职员没有联系方式的情况,直接给出代码:

List list = new List();

foreach (var staff in listStaff)

{

JsonObject json = new JsonObject();

json.Add("ID", staff.ID.ToString());

json.Add("Name", staff.Name);

//联系方式

var contact = listContact.FirstOrDefault(m => m.StaffID == staff.ID);

if (contact != null)

{

JsonObject jsonContact = new JsonObject();

jsonContact.Add("Email", contact.Email);

//这里注意,将 Contact 对象序列化后的json串添加到了json对象

json.Add("Contact", contact.ToJson());

}

//将json对象序列化再添加到list

list.Add(json.ToJson());

}

//得到最终json串

var result = string.Format("[{0}]", string.Join(",", list));

得到的 json:

[

{

"ID": 2,

"Name": "小李"

},

{

"ID": 3,

"Name": "小王",

"Contact": {

"StaffID": 3,

"Email": "xiaowang@163.com"

}

}

]

而反序列化时,使用 FromJson() 即可:

user u = new user();

u.num = 110;

u.name = "张三";

u.weight = 58.3m;

//序列化

string ujson = u.tojson();

//反序列化

user udejson = ujson.fromjson();

console.writeline("json反序列化:" + udejson.tostring());

本文简单介绍了下使用 ServiceStack.Text 来序列化 json,希望对没有使用过的朋友有些帮助。

查看原文