我们在做开发的时候,很多时候需要和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来序列化所需的数据的更多相关文章

  1. 【ASP.NET Web API教程】6.2 ASP.NET Web API中的JSON和XML序列化

    谨以此文感谢关注此系列文章的园友!前段时间本以为此系列文章已没多少人关注,而不打算继续下去了.因为文章贴出来之后,看的人似乎不多,也很少有人对这些文章发表评论,而且几乎无人给予“推荐”.但前几天有人询 ...

  2. ASP.NET Web API中的JSON和XML序列化

    ASP.NET Web API中的JSON和XML序列化 前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok ...

  3. (转)python常用模块(模块和包的解释,time模块,sys模块,random模块,os模块,json和pickle序列化模块)

    阅读目录 1.1.1导入模块 1.1.2__name__ 1.1模块 什么是模块: 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代 ...

  4. Python下Json和Msgpack序列化比较

     最近用Python时,遇到了序列化对象的问题,传统的json和新型序列化工具包msgpack都有涉及,于是做一个简单的总结: 通俗的讲:序列化:将对象信息转化为可以存储或传输的形式:反序列化:把这个 ...

  5. php json与xml序列化/反序列化

    在web开发中对象的序列化与反序列化经常使用,比较主流的有json格式与xml格式的序列化与反序列化,今天想写个jsop的小demo,结果发现不会使用php序列化,查了一下资料,做个笔记 简单数组js ...

  6. Java下利用Jackson进行JSON解析和序列化

    Java下利用Jackson进行JSON解析和序列化   Java下常见的Json类库有Gson.JSON-lib和Jackson等,Jackson相对来说比较高效,在项目中主要使用Jackson进行 ...

  7. .net MVC 使用 JSON JavaScriptSerializer 进行序列化或反序列化时出错,字符串的长度超过了为 maxJsonLength 属性设置的值

    在.net mvc的controller中,方法返回JsonResult,一般我们这么写: [HttpPost] public JsonResult QueryFeature(string url, ...

  8. 使用JSON JavaScriptSerializer 进行序列化或反序列化时出错。字符串的长度超过了为 maxJsonLength属性

    "/"应用程序中的服务器错误.使用 JSON JavaScriptSerializer 进行序列化或反序列化时出错.字符串的长度超过了为 maxJsonLength 属性设置的值. ...

  9. json and pickle 序列化

    前言 文件只能存储字符串.二进制,若把内存的数据对象存到硬盘   从硬盘里读取数据,里面不止是字符串的类型,因此用到了json and pickle 序列化 json序列化 作用:用于不同语言进行的数 ...

随机推荐

  1. 作业3.2:psp

    PSP2.1 Personal Software Process Stages Time Planning 计划 20min Estimate 估计这个任务需要多长时间 3.5h Developmen ...

  2. js模版引擎handlebars.js实用教程——关于HTML编码

    返回目录 <!DOCTYPE html> <html> <head> <META http-equiv=Content-Type content=" ...

  3. IOS 公共类-MyMBProgressUtil Progress显示

    IOS 公共类-MyMBProgressUtil Progress显示 此公共类用于显示提示框,对MBProgress的进一步封装.可以看下面的代码 接口: @interface MyMBProgre ...

  4. 用VC编译lua源码,生成lua语言的解释器和编译器

    用VC编译lua源码,生成lua语言的解释器和编译器 1.去网址下载源码 http://www.lua.org/download.html 2.装一个VC++,我用的是VC6.0 3.接下来我们开始编 ...

  5. Atitit sql执行计划

    Atitit sql执行计划 1.1. 首先要搞明白什么叫执行计划? 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的 Oracle中的执行计划 ...

  6. Atititi.名字 姓名 name 起名naming spec 的构成结构规范v2 qc2.docx

    Atititi.名字 姓名 name 起名naming spec 的构成结构规范v2 qc2.docx 1.1. 职业名 官职等 amir 阿米尔 放前面1 1.2. 本名1 1.3. 父名,祖名,一 ...

  7. Atitit qzone qq空间博客自动点赞与评论工具的设计与实现

    Atitit qzone qq空间博客自动点赞与评论工具的设计与实现 Qzone发送评论的原理 首先,有个a标签, <a class="c_tx3" href="j ...

  8. fir.im Weekly - 如何打造真正的工程师文化

    好的工程师,无法忍受低效且无趣的工作.优秀的技术团队应该自上而下的地推进技术平台化建设.DevOps.自动化构建.测试和部署流程,积极采用合适的第三方工具或创造工具,进行周期性的前沿技术分享等等. 先 ...

  9. Spring Cloud 配置服务

    Spring Cloud 配置服务 1. 配置服务简介 产生背景: 传统开发中,我们通常是将系统的业务无关配置(数据库,缓存服务器)在properties中配置,在这个文件中不会经常改变,但随着系统规 ...

  10. VS2013模块对于SAFESEH映像是不安全的解决方法

    常见报错:error LNK2026: 模块对于 SAFESEH 映像是不安全的 解决方法:右键打开项目属性 -> 链接器 -> 命令行 -> 其他选项 (D) 中加入  /SAFE ...