使用Json.NET来序列化所需的数据
我们在做开发的时候,很多时候需要和Json数据格式打交道,如Web开发里面,很多时候,数据通过Json进行传递到页面上,然后在进行处理的。而使用Json的时候,我们很多时候会涉及到几个序列化对象的使用:DataContractJsonSerializer,JavaScriptSerializer 和 Json.NET。大多数人都会选择性能以及通用性较好Json.NET,这个不是微软的类库,但是一个开源的世界级的Json操作类库,从下面的性能对比就可以看到它的其中之一的性能优点。

Json.NET能很好序列化或者反序列化.NET的各种类型数据,而且它的另一个优点,是可以配置Attribute属性,指定输出的属性的名称或者是否输出,这点我非常喜欢。
JSON(JavaScript Object Notation,JavaScript对象表示法)是一种轻量级的数据交换格式。JSON是“名值对”的集合。结构由大括号'{}',中括号'[]',逗号',',冒号':',双引号'“”'组成,包含的数据类型有Object,Number,Boolean,String,Array, NULL等。
1、在Web中使用Json数据
在我的基于MVC+EasyUI的Web开发框架中,Web界面层大量使用了Ajax方式获取所需数据,然后绑定到树列表控件或者其他界面控件里面,在前面的一些Web框架随笔系列里面,我介绍过很多Json格式的操作。
1)基于MVC4+EasyUI的Web开发框架经验总结(3)- 使用Json实体类构建菜单数据
2)基于MVC4+EasyUI的Web开发框架经验总结(2)- 使用EasyUI的树控件构建Web界面
如在MVC的视图里面,通过Web请求的Json数据后初始化树控件的代码如下所示
//初始化组织机构列表
function initDeptTreeview() {
$("#loading").show(); $('#treeDept').tree({
url: '/User/GetMyDeptTreeJson?userId=@Session["UserId"]',
onClick: function (node) {
loadDataByOu(node.id);
}
}); $("#loading").fadeOut(500);
}
或者用户角色的初始化界面代码
$('#lbxRoles').empty();
$.getJSON("/Role/GetRolesByUser?r=" + Math.random() + "&userid=" + info.ID, function (json) {
$.each(json, function (i, item) {
$('#lbxRoles').append('<option value="' + item.ID + '">' + item.Name + '</option>');
});
});
前面说过,Json.NET具有属性配置功能,可以指定某个属性是否输出,或者输出的名称转义等。默认情况下,Json.Net序列化后结果中的字段名称和类中属性的名称一致,如果想自定义序列化后的字段名称,可以使用JsonProperty。
我们知道,EasyUI的Tree控件里面,它的数据格式,除了一个id和text是必须的之外,它的很多属性是可选的,也就是说在Json里面,可以不输出某个属性的内容。这个通过配置
[JsonProperty( NullValueHandling = NullValueHandling.Ignore)]
就可以忽略某个属性的输出了,如果这个属性的值为null的话。
树控件的数据还有一个checked属性, 如果没有转义功能,我们需要指定属性为checked, 而checked是C#里面的保留关键字,不能使用,那么就没办法了。而Json.NET提供了转义功能的配置Attribute,很好解决问题,如下所示。
[JsonProperty(PropertyName = "checked", NullValueHandling = NullValueHandling.Ignore)]
public bool? Checked { get; set; }
因此整个EasyUI的Tree数据对象信息,在C#里面可以定义为如下所示(这里可以忽略DataContract、DataMember的定义)。
/// <summary>
/// 定义EasyUI树的相关数据,方便控制器生成Json数据进行传递
/// </summary>
[DataContract]
[Serializable]
public class EasyTreeData
{
/// <summary>
/// ID
/// </summary>
[DataMember]
public string id { get; set; } /// <summary>
/// 节点名称
/// </summary>
[DataMember]
public string text { get; set; } /// <summary>
/// 是否展开
/// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
[DataMember]
public string state { get; set; } /// <summary>
/// 图标样式
/// </summary>
[DataMember]
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string iconCls { get; set; }
[JsonProperty(PropertyName = "checked", NullValueHandling = NullValueHandling.Ignore)]
[DataMember(Name="checked")]
public bool? Checked { get; set; }
/// <summary>
/// 子节点集合
/// </summary>
[DataMember]
public List<EasyTreeData> children { get; set; }
使用上的实体类,并使用Json.NET来序列化我们的数据,我们可能得到下面的Json数据。
[
{
id: "-1",
text: "无",
state: "open",
checked: true,
children: [ ]
},
{
id: "",
text: "总经办",
state: "open",
iconCls: "icon-group",
children: [ ]
}
]
我们从上面的Json数据可以看到,Checked属性顺利转换为checked的名称属性,标记为[JsonProperty(NullValueHandling = NullValueHandling.Ignore)] ,而值为null的属性,将不会出现在Json的字符串里面了。
这个在某种情形下,正好就是我们所需要的。
2、在微信接口开发中使用Json
微信API的接口,大量使用了Json数据,不仅很多返回的数据是使用Json表达,而且其Post的数据,也多数使用Json数据格式,如在我的前两篇随笔《C#开发微信门户及应用(5)--用户分组信息管理》 、《C#开发微信门户及应用(4)--关注用户列表及详细信息管理》
里面介绍的内容,微信的很多接口都使用了Json数据。
如返回关注者列表的Json数据,就是如下所示。
{"total":2,"count":2,"data":{"openid":["","OPENID1","OPENID2"]},"next_openid":"NEXT_OPENID"}
创建用户分组,返回的数据格式如下,同样也是Json数据。
{
"group": {
"id": 107,
"name": "test"
}
}
通过下面基于Json.NET的Json数据的转换,就可以顺利从Json字符串转换为相应的实体对象了。
/// <summary>
/// Json字符串操作辅助类
/// </summary>
public class JsonHelper<T> where T : class, new()
{
/// <summary>
/// 检查返回的记录,如果返回没有错误,或者结果提示成功,则不抛出异常
/// </summary>
/// <param name="content">返回的结果</param>
/// <returns></returns>
private static bool VerifyErrorCode(string content)
{
if (content.Contains("errcode"))
{
ErrorJsonResult errorResult = JsonConvert.DeserializeObject<ErrorJsonResult>(content);
//非成功操作才记录异常,因为有些操作是返回正常的结果({"errcode": 0, "errmsg": "ok"})
if (errorResult != null && errorResult.errcode != ReturnCode.请求成功)
{
string error = string.Format("微信请求发生错误!错误代码:{0},说明:{1}", (int)errorResult.errcode, errorResult.errmsg);
LogTextHelper.Error(errorResult); throw new WeixinException(error);//抛出错误
}
}
return true;
} /// <summary>
/// 转换Json字符串到具体的对象
/// </summary>
/// <param name="url">返回Json数据的链接地址</param>
/// <returns></returns>
public static T ConvertJson(string url)
{
HttpHelper helper = new HttpHelper();
string content = helper.GetHtml(url);
VerifyErrorCode(content); T result = JsonConvert.DeserializeObject<T>(content);
return result;
}
}
而如果要把对象转换为Json字符串格式的数据,那么代码也很简单。
JsonConvert.SerializeObject(obj, Formatting.Indented);
使用Json.NET来序列化所需的数据的更多相关文章
- 【ASP.NET Web API教程】6.2 ASP.NET Web API中的JSON和XML序列化
谨以此文感谢关注此系列文章的园友!前段时间本以为此系列文章已没多少人关注,而不打算继续下去了.因为文章贴出来之后,看的人似乎不多,也很少有人对这些文章发表评论,而且几乎无人给予“推荐”.但前几天有人询 ...
- ASP.NET Web API中的JSON和XML序列化
ASP.NET Web API中的JSON和XML序列化 前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok ...
- (转)python常用模块(模块和包的解释,time模块,sys模块,random模块,os模块,json和pickle序列化模块)
阅读目录 1.1.1导入模块 1.1.2__name__ 1.1模块 什么是模块: 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代 ...
- Python下Json和Msgpack序列化比较
最近用Python时,遇到了序列化对象的问题,传统的json和新型序列化工具包msgpack都有涉及,于是做一个简单的总结: 通俗的讲:序列化:将对象信息转化为可以存储或传输的形式:反序列化:把这个 ...
- php json与xml序列化/反序列化
在web开发中对象的序列化与反序列化经常使用,比较主流的有json格式与xml格式的序列化与反序列化,今天想写个jsop的小demo,结果发现不会使用php序列化,查了一下资料,做个笔记 简单数组js ...
- Java下利用Jackson进行JSON解析和序列化
Java下利用Jackson进行JSON解析和序列化 Java下常见的Json类库有Gson.JSON-lib和Jackson等,Jackson相对来说比较高效,在项目中主要使用Jackson进行 ...
- .net MVC 使用 JSON JavaScriptSerializer 进行序列化或反序列化时出错,字符串的长度超过了为 maxJsonLength 属性设置的值
在.net mvc的controller中,方法返回JsonResult,一般我们这么写: [HttpPost] public JsonResult QueryFeature(string url, ...
- 使用JSON JavaScriptSerializer 进行序列化或反序列化时出错。字符串的长度超过了为 maxJsonLength属性
"/"应用程序中的服务器错误.使用 JSON JavaScriptSerializer 进行序列化或反序列化时出错.字符串的长度超过了为 maxJsonLength 属性设置的值. ...
- json and pickle 序列化
前言 文件只能存储字符串.二进制,若把内存的数据对象存到硬盘 从硬盘里读取数据,里面不止是字符串的类型,因此用到了json and pickle 序列化 json序列化 作用:用于不同语言进行的数 ...
随机推荐
- 作业三:PSP耗时
请同学们参照教材<构建之法>2.3节表2-4 PSP2.1汇报自己在完成四则运算编程时候的时间分布,发布到博客上. 个人项目耗时情况分析 PSP Personal Software Pro ...
- Linux split拆分文件
200 ? "200px" : this.width)!important;} --> 介绍 split可以将一个大文件拆分成指定大小的多个文件,并且拆分速度非常的快,拆分一 ...
- redis(二)高级用法
redis(二)高级用法 事务 redis的事务是一组命令的集合.事务同命令一样都是redis的最小执行单元,一个事务中的命令要么执行要么都不执行. 首先需要multi命令来开始事务,用exec命令来 ...
- 如何给开源的DUILib支持Accessibility
最近的工作是给开源的DUILib支持Accessibility, 一些经验记录并分享下. 微软的Accessibility其实Windows平台上一个挺重要的东西, 尽管在国内不受重视,但是如果你的软 ...
- PowerDesigner实用操作
1. 让PhysicalDiagram里的表显示字段名Tools→Display Preferences→在General Settings里选择Table→点击Advanced→选择Form下的Co ...
- 搭建LNAMP环境(四)- 源码安装PHP7
上一篇:搭建LNAMP环境(三)- 源码安装Apache2.4 一.安装PHP7 1.yum安装编译php需要的包 yum -y install libxml2 libxml2-devel curl- ...
- Form的enctype="multipart/form-data"作用
<form class="form-horizontal" role="form" method="post" action=&quo ...
- web前端攻击详解
前端攻击成因 在web网页的脚本中,有些部分的显示内容会依据外界输入值而发生变化,而如果这些声称html的程序中存在问题,就会滋生名为跨站脚本的安全隐患 XSS跨站脚本攻击: 英文全称cross-si ...
- Grunt 安装与配置环境
当时学习 Grunt 的时候,真是很头疼.分了两个时间段,学习了两次才硬啃下来,之后才能用在项目中.主要原因我认为是学习资料和文档上面写的太高端了.这类的文档或者资料有个显著特点,上来先简单介绍一下这 ...
- TSql Top 用法
第一部分:TSql Top 有两种用法 1,限制查询结果集返回的行数或总行数的百分比. 当将 TOP 与 ORDER BY 子句结合使用时,结果集限制为前 N 个已排序行:否则,以未定义的顺序返回前 ...