zoukankan      html  css  js  c++  java
  • .NET Framework 3.5中序列化成JSON数据及JSON数据的反序列化,以及jQuery的调用JSON

    原贴地址:http://bbs.zkinfo.com/thread-80510-1-1.html

    最近要用到jQuery调用JSON,但遇到几个问题,正面将记录下遇到的问题及解决方法。
    在将Object序列化成JSON时普遍是使用以下几种方式:
    1. 第三方组件Newtonsoft.Json.dll来序列化。
    2. 直接用StringBuilder拼接字符串。
    3. .NET3.5中的DataContractJsonSerializer
    很多人使用的是第三方组件来序列化,但.NET3.5中已经提供了对序列化及反序列化很好的支持,直接使用就行了,而拼接字符串的方式就更原始了,要对一些字符串进行处理也容易出错。所以还是选择了DataContractJsonSerializer,感觉非常方便。下面就看怎么来实了:
    首先创建项目,添加必要的程序集引用:System.ServiceModel.Web及System.Runtime.Serialization
    创建ashx文件以便jQuery调用,当然也可以根据自己的需要创建WebServices或其它文件,代码如下
    Demo.ashx
    Demo.ashx
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    using System.Web;
    using System.Web.Services;

    namespace JSONDemo
    {
        ///
    <summary>
    /// $codebehindclassname$ 的摘要说明
        ///
    </summary>
        [WebService(Namespace =
    "http://tempuri.org/")]
        [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
        public
    class Demo : IHttpHandler
        {
            public
    void ProcessRequest(HttpContext context)
            {
                context.Response.ContentType =
    "text/plain";
                List<User> users =
    new List<User>();
                #region AddUser
                users.Add(new User
                {
                    UserId =
    1,
                    UserName =
    "张三",
                    Birthday = DateTime.Parse("1982/1/1")
                });
                users.Add(new User
                {
                    UserId =
    2,
                    UserName =
    "李四",
                    Birthday = DateTime.Parse("1983/2/1")
                });
                users.Add(new User
                {
                    UserId =
    3,
                    UserName =
    "王五",
                    Birthday = DateTime.Parse("1984/3/1")
                });
                #endregion
    string json = JsonHelper.Serialize(users);
                //context.Response.Write("序列化:\r\n");
                context.Response.Write(json);
                //User u = JsonHelper.Deserialize<User>("");
                List<User> users2 = JsonHelper.Deserialize<List<User>>(json);
                //context.Response.Write("\r\n反序列化:\r\n");

    foreach (User item in users2)
                {
                    //context.Response.Write(string.Format("UserId:{0},UserName:{1},Birthday:{2}\r\n", item.UserId, item.UserName, item.Birthday));
                }
            }

            public
    bool IsReusable
            {
                get
                {
                    return
    false;
                }
            }
        }

        ///
    <summary>
    /// 数据实体
        ///
    </summary>

    //[Serializable]这里是需要注意的地方

    public
    class User
        {
            public
    int UserId { get; set; }
            public
    string UserName { get; set; }
            public DateTime Birthday { get; set; }
        }

        ///
    <summary>
    /// JSON序列化与反序列化辅助类
        ///
    </summary>

    public
    class JsonHelper
        {
            public
    static
    string Serialize<T>(T data)
            {
                System.Runtime.Serialization.Json.DataContractJsonSerializer serializer =
    new System.Runtime.Serialization.Json.DataContractJsonSerializer(data.GetType());
                using (MemoryStream ms =
    new MemoryStream())
                {
                    serializer.WriteObject(ms, data);
                    return Encoding.UTF8.GetString(ms.ToArray());
                    //ms.Position = 0;
                    //using (StreamReader sr = new StreamReader(ms))
                    //{
                    //    return sr.ReadToEnd();
                    //}
                }
            }

            public
    static T Deserialize<T>(string json)
            {
                T obj = Activator.CreateInstance<T>();
                using (MemoryStream ms =
    new MemoryStream(Encoding.UTF8.GetBytes(json)))
                {
                    System.Runtime.Serialization.Json.DataContractJsonSerializer serializer =
    new System.Runtime.Serialization.Json.DataContractJsonSerializer(obj.GetType());
                    return (T)serializer.ReadObject(ms);
                }
            }
        }
    }

    访问Demo.ashx显示结果如下,对了这就是我们想要的数据:
    [{"Birthday":"\/Date(378662400000+0800)\/","UserId":1,"UserName":"张三"},{"Birthday":"\/Date(412876800000+0800)\/","UserId":2,"UserName":"李四"},{"Birthday":"\/Date(446918400000+0800)\/","UserId":3,"UserName":"王五"}]

    jQuery调用JSON代码:

    jQuery调用
    <script type="text/javascript">
        $().ready(function() {
            $.getJSON("Demo.ashx", function(data) {
                var msg = [data.length];
                for (var i in data) {
                    msg =
    "UserId:"
    + data.UserId +
    ",UserName:"
    + data.UserName +
    ",Birthday:"
    + data.Birthday;
                }
                alert(msg.join('\n'));
            });
        });
    </script>

    但在实现时遇到几个问题:
    1. DateTime类型在实例化时如果未对DateTime属性赋值序列化时(即:DateTime.MinValue)将会报错:指定的参数已超出有效值的范围。参数名: value
    在转换为 UTC 时大于 DateTime.MaxValue 或小于 DateTime.MinValue 的 DateTime 值无法系列化为 JSON。]
    根据提示是DateTime值小于DateTime.MinValue时造成的,但实际上未赋值时DateTime默认就是MinValue了,不存在小于MinValue。莫然其妙的一个问题,但如果DateTime值为DateTime.MinValue.AddDays(1),就没问题了。所以提示应该改成必须大于MinValue,不知道这算不算一个小BUG?
    2. 当最开始序列化时发现虽然序列化的结果却是下面这样一堆字符:

    [{"<Birthday>k__BackingField":"\/Date(378662400000+0800)\/","<UserId>k__BackingField":1,"<UserName>k__BackingField":"张三"},{"<Birthday>k__BackingField":"\/Date(412876800000+0800)\/","<UserId>k__BackingField":2,"<UserName>k__BackingField":"李四"},{"<Birthday>k__BackingField":"\/Date(446918400000+0800)\/","<UserId>k__BackingField":3,"<UserName>k__BackingField":"王五"}]

    经查询是因为实体类声明了可序列化造成的:
    [Serializable]
    public class User
    当然把[Serializable]去掉,结果就正常了,可这样实体类就不能实例化了?当然我们可以用其它方法来解决这一问题,用WCF中的数据契约声明实体就行(别忘了在所有属性上加上[DataMember]不然这些属性都不可访问哦。)[DataContract]
    public class User
    {
         [DataMember]
         public int UserId{get;set;}
    }

    完整DEMO下载:JSONDemo.rar

    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lee576/archive/2009/01/08/3736977.aspx

  • 相关阅读:
    python_24_test
    python_23_tuple
    python_22_enumerate
    python_20_列表
    python_21_copy
    python_19_编码解码
    python_18_三元运算
    python_16_自己建立模块
    关于主键(PRIMARY KEY)和自增(AUTO_INCREMENT)结合使用的知识点
    MySQL root用户忘记密码怎么办?修改密码方法:skip-grant-tables
  • 原文地址:https://www.cnblogs.com/68681395/p/1498343.html
Copyright © 2011-2022 走看看