• 使用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:
    "6", 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);
  • 相关阅读:
    BZOJ 3260: 跳 (组合恒等式)
    BZOJ 1924 [SDOI 2010] 所驼门王的宝藏 (优化建图+tarjan+最长链)
    BZOJ 3451Normal (点分治+FFT)
    BZOJ 2213: [Poi2011]Difference (DP)
    BZOJ 3251 树上三角形 (暴力)
    [HNOI2008]明明的烦恼
    HDU 1521 排列组合
    [HNOI2008]神奇的国度
    [HNOI2008]遥远的行星
    [HNOI2001]软件开发
  • 原文地址:https://www.cnblogs.com/wuhuacong/p/3698122.html
Copyright © 2020-2023  润新知