.NET Framework 3.5中序列化成JSON数据及JSON数据的反序列化,以及jQuery的调用JSON

最近要用到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 


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 { getset; }
        public string UserName { getset; }
        public DateTime Birthday { getset; }
    }

    /// <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代码:


<script type="text/javascript">
    $().ready(function() {
        $.getJSON("Demo.ashx", function(data) {
            var msg = [data.length];
            for (var i in data) {
                msg[i] = "UserId:" + data[i].UserId + ",UserName:" + data[i].UserName + ",Birthday:" + data[i].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;}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值