当前位置: 首页 > news >正文

.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

相关文章:

  • 7.1 查找的基本概念、顺序查找、折半查找、分块查找(索引顺序查找)
  • c# 反射的使用方法,不知道是不是最全的
  • 7.2 B树的定义、查找效率分析、B树的高度、插入和删除
  • RadControl For Asp.net的官方API
  • 7.3 B+树
  • 7.4 散列查找(散列表、常见的散列函数、除留余数法、直接定址法、数字分析法、平方取中法)
  • 对话实录——什么叫做无赖
  • 7.5 散列查找(开放定址法、线性探测法、平方探测法、伪随机序列法、再散列法)
  • 8.1 排序的基本概念(时间复杂度、空间复杂度、稳定性、内部排序、外部排序、可视化网站)
  • 8.2 插入排序(算法实现、效率分析、折半优化)
  • 手机二维码~~~ZXing简介
  • 8.3 希尔排序(算法实现、性能分析)
  • 8.4 冒泡排序(交换排序、算法实现、性能分析)
  • WPF的RichTextBox在处理汉字时的小BUG
  • 8.5 快速排序(交换排序、算法实现、性能分析)
  • [译] React v16.8: 含有Hooks的版本
  • CSS 专业技巧
  • java第三方包学习之lombok
  • Mithril.js 入门介绍
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • 基于webpack 的 vue 多页架构
  • 深入 Nginx 之配置篇
  • 延迟脚本的方式
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • 基于django的视频点播网站开发-step3-注册登录功能 ...
  • ​LeetCode解法汇总2304. 网格中的最小路径代价
  • #162 (Div. 2)
  • #android不同版本废弃api,新api。
  • $.ajax()参数及用法
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (2)Java 简介
  • (六)什么是Vite——热更新时vite、webpack做了什么
  • (图)IntelliTrace Tools 跟踪云端程序
  • (万字长文)Spring的核心知识尽揽其中
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)
  • (转)winform之ListView
  • (转载)深入super,看Python如何解决钻石继承难题
  • .NET 中使用 Mutex 进行跨越进程边界的同步
  • .NET/C# 中你可以在代码中写多个 Main 函数,然后按需要随时切换
  • .net操作Excel出错解决
  • .NET单元测试
  • .NET牛人应该知道些什么(2):中级.NET开发人员
  • @Controller和@RestController的区别?
  • @JsonSerialize注解的使用
  • [AIGC] 如何建立和优化你的工作流?
  • [Android]竖直滑动选择器WheelView的实现
  • [BZOJ1040][P2607][ZJOI2008]骑士[树形DP+基环树]
  • [c]统计数字
  • [Gym-102091E] How Many Groups
  • [HackMyVM]靶场 Quick3
  • [Java]快速入门二叉树,手撕相关面试题
  • [JAVA设计模式]第二部分:创建模式
  • [Linux] Linux入门必备的基本指令(不全你打我)
  • [Linux打怪升级之路]-信号的保存和递达