利用JavascriptSerializer类 进行Json对象的序列化和反序列化
1. 首先, JavascriptSerializer类所在名空间: using System.Web.Script.Serialization;
2. 相关的3篇文章, 标记下:
使用JavaScriptSerializer进行JSON序列化
注意: 是复杂对象.
JSON是Javascript中常用的数据格式,然而,在.NET 2.0中没有内置序列化JSON的类,原因估计是当时Ajax尚未兴起。后来就有人写了一个Json.NET类库。.NET 3.5新增了一个把对象序列化为JSON字符串的类JavaScriptSerializer。这个类位于System.Web.Script.Serialization名字空间中(非Web项目需要添加System.Web.Extensions.dll引用),其使用方法也是非常简单的:
// 分类
public class Category
{
public int CategoryId { get; set; } // 分类编号
public string CategoryName { get; set; } // 分类名
}
Category testCategory = new Category()
{
CategoryId = 1,
CategoryName = "Test"
};
JavaScriptSerializer serializer = new JavaScriptSerializer();
Console.Write(serializer.Serialize(testCategory)); // 调用Serialize方法进行序列化
如果不希望序列化某个属性,可以给该属性标记为ScriptIgnore:
public class Category
{
[ScriptIgnore]
public int CategoryId { get; set; }
public string CategoryName { get; set; }
}
事实上,Serialize方法是个递归方法,会递归地序列化对象的属性,因此在序列化一个复杂对象(比如DataTable)时往往会出现“循环引用”的异常,这时候就需要针对复杂类型自定义一个转换器。下面是DataTable的转换器,原理是把DataTable转换成一个字典列表后再序列化:
/// <summary>
/// DataTable JSON转换类
/// </summary>
public class DataTableConverter : JavaScriptConverter
{
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
DataTable dt = obj as DataTable;
Dictionary<string, object> result = new Dictionary<string, object>();
List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
foreach (DataRow dr in dt.Rows)
{
Dictionary<string, object> row = new Dictionary<string, object>();
foreach (DataColumn dc in dt.Columns)
{
row.Add(dc.ColumnName, dr[dc.ColumnName]);
}
rows.Add(row);
}
result["Rows"] = rows;
return result;
}
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
throw new NotImplementedException();
}
/// <summary>
/// 获取本转换器支持的类型
/// </summary>
public override IEnumerable<Type> SupportedTypes
{
get { return new Type[] { typeof(DataTable) }; }
}
}
所有自定义的转换器都要继承于JavaScriptConverter,并实现Serialize、Deserialize方法和SupportedTypes属性,其中SupportedTypes属性用于枚举此转换器支持的类型。定义了一个新的转换器后需要将其实例化并注册到JavaScriptSerializer对象:
JavaScriptSerializer JsonSerializer = new JavaScriptSerializer();
JsonSerializer.RegisterConverters(
new JavaScriptConverter[]
{
new DataTableConverter()
}
);
对于DateTime类型,JavaScriptSerializer默认将其序列化为 "\/Date(ticks)\/" 格式的字符串,这明显需要Javascript作进一步的解释,非常多余。笔者建议各位根据需要添加一个DateTime类型的转换器。
====================================
第二篇:
Asp.net Ajax WebService 实现循环引用(自定义JavascriptConverter)
2008-07-18 15:49 by Henry Cui, 1476 visits, 收藏, 编辑
准备技术:
1.简单的WebService编写;
2.了解Asp.net Ajax 客户端访问WebService
内容:
asp.net ajax框架在去年看过,只是些基本的使用,并没有过多的去研究它的原理。最近在一个项目中要实现客户端访问WebService并返回DataTable类型的数据,当我调用一个返回DataTable的方法时,不能返回成功,在错误的回调函数中告诉我DataTable是一个循环应用类型,不能序列化。当是想过把DataTable替换成其他类型的数据如ArrayList或则Array等,可是有点心不甘,所以查过各个方面的资料,告诉我微软已经提供了一个解决DataTable的JavaScriptConverter的dll文件,当我在web.config中添加了对这个JavascriptConverter引用即可以将DataTable序列化成Json字符串了。
好了,废话不多说了。下面就自己来做个循环应用的实例,并通过自定义JavascriptConverter来解决循环引用的问题。本文只会简单的介绍下服务器端序列化数据类型到Json的过程,不会太深入。
首先先来定义两个类,想了半天最好的实例就是一对夫妻,一个老公只有一个老婆,这是婚姻法规定的,所以老公类型跟老婆类型就可以达到实例中的循环引用。看下两个类型的类试图:
其实两个类里面的内容都很简单,Husband.cs:
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.ComponentModel;
public class Husband
{
private string _firstName;
public string FirstName
{
get { return _firstName; }
set { _firstName = value; }
}
private string _lastName;
public string LastName
{
get { return _lastName; }
set { _lastName = value; }
}
private Wife _wife;
public Wife Wife
{
get { return _wife; }
set { _wife = value; }
}
}
Wife.cs:
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.ComponentModel;
public class Wife
{
private string _firstName;
public string FirstName
{
get { return _firstName; }
set { _firstName = value; }
}
private string _lastName;
public string LastName
{
get { return _lastName; }
set { _lastName = value; }
}
private Husband _husband;
public Husband Husband
{
get { return _husband; }
set { _husband = value; }
}
}
然后我定义了个Webservice类用来提供Client的访问,HusbandService.cs:
using System;
using System.Collections;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Linq;
using System.Web.Script.Services;
/// <summary>
/// Husband's Method
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class HusbandService : System.Web.Services.WebService {
public HusbandService () {
//Uncomment the following line if using designed components
//InitializeComponent();
}
[WebMethod]
public Husband GetHusband()
{
Husband hansband = new Husband();
hansband.FirstName = "Henllyee";
hansband.LastName = "Cui";
Wife wife = new Wife();
wife.FirstName = "Throwen";
wife.LastName = "Yang";
hansband.Wife = wife;
wife.Husband = hansband;
return hansband;
}
}
我在一个asp.net 页面中通过asp.net ajax对GetHusband()的应用的,JavascriptConverter.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="JavascriptConverter.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>JavaScriptConverter Demo</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="scriptManager" runat="server">
<Services>
<asp:ServiceReference Path="~/HusbandService.asmx" />
</Services>
</asp:ScriptManager>
<script language="javascript" type="text/javascript">
function getServiceHasband()
{
HusbandService.GetHusband(onSuccess,onFailed);
}
function onSuccess(result)
{
alert(result.FirstName);
}
function onFailed(error)
{
alert(error.get_message());
}
window.οnlοad=function()
{
var btnGet = $get("btnGet");
if(btnGet)
{
btnGet.οnclick=getServiceHasband;
}
}
</script>
<input type="button" id="btnGet" value="Get HusBand" />
</div>
</form>
</body>
</html>
运行后当我们点击按钮是,会弹出出错的信息,告诉我们Husband是一个循环引用类型,不能序列化。这时我们可以通过编写对应的JavascriptConverter来告诉服务器端如何去序列化。
我们自定的JavascriptConverter必须继承于JavascriptConverter(JavascriptConverter参考文档),然后去重写里面的两个方法跟一个属性:
1.Deserialize:如何反序列化一个Jason到这个Converter类型;
2.Serialize:如何序列化支持的对象到一个Jason;
3.SupportedTypes:这个Converter支持的类型。
好了下面我们定义下一个Converter来支持循环引用,现在我们先定义如何将去序列化,HusbandConverter.cs:
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Web.Script.Serialization;
using System.Collections.Generic;
/// <summary>
/// Husband's Converter
/// </summary>
public class HusbandConverter:JavaScriptConverter
{
public HusbandConverter()
{
}
/// <summary>
///
/// </summary>
/// <param name="dictionary"></param>
/// <param name="type"></param>
/// <param name="serializer"></param>
/// <returns></returns>
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
throw new NotImplementedException();
}
/// <summary>
/// Serizlize a json
/// </summary>
/// <param name="obj"></param>
/// <param name="serializer"></param>
/// <returns></returns>
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
Husband husband = (Husband)obj;
IDictionary<string,object> dictionary = new Dictionary<string,object>();
husband.Wife.Husband = null;
dictionary["FirstName"] = husband.FirstName;
dictionary["LastName"] = husband.LastName;
dictionary["Wife"] = husband.Wife;
return dictionary;
}
/// <summary>
/// Support Types
/// </summary>
public override System.Collections.Generic.IEnumerable<Type> SupportedTypes
{
get
{
yield return typeof(Husband);
}
}
}
然后我们在web.config中注册这样一段对这个Converter的引用:
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization>
<converters>
<add name="HusbandConvert" type="HusbandConverter,App_Code"/>
</converters>
</jsonSerialization>
</webServices>
</scripting>
</system.web.extensions>
这下我们再运行时,去点击按钮就能返回“Henllyee”。
在上面中我们首先重写了SupportedTypes属性去告诉系统我这个Converter支持那些类型的数据。然后我们去重写了Serialize方法,其实我们在这里只是把husband.Wife.Husband设置为了null,让它不去循环引用了,所以这样就破坏原来的类的本意。但是我们可以在客户端再去完善它,再在客户端设置husband.Wife.Husband=husband即可了。
下面我们再看如何进行反序列化了。首先我们在webservice中先添加一个方法,来传入Husband对象
[WebMethod]
public string GetHusbandInfo(Husband hansband)
{
Debug.Assert(hansband.Wife.Husband == hansband);
return String.Format(
"Husband's :{0}\n Wife:{1}",
hansband.FirstName + " " + hansband.LastName,
hansband.Wife.FirstName + " " + hansband.LastName);
}
然后我们再去把反序列化实现下:
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
Husband husband = new Husband();
husband.FirstName = (string)dictionary["FirstName"];
husband.LastName = (string)dictionary["LastName"];
husband.Wife = serializer.ConvertToType<Wife>(dictionary["Wife"]);
husband.Wife.Husband = husband;
return husband;
}
最后我们在客户端进行调用:
function getHusbandInfo()
{
var husband = new Object();
husband.FirstName="Henllyee";
husband.LastName="Cui";
var wif = new Object();
wif.FirstName="Erry";
wif.LastName="Du";
husband.Wife=wif;
HusbandService.GetHusbandInfo(husband,onGetInfoSucceded,onFailed);
}
function onGetInfoSucceded(result)
{
alert(result);
}
具体的前台的脚本就不在给出,通过运行我们会发现反序列化是成功的。
事情是这样的,ASP.NET AJAX调用服务器端的代码,返回一个复杂类型,GongWenList,其中GongWenList有两个属性,(1):List<GongWen>类型的ListGongWen,(2)简单的int类型的iItemCount;其中GongWen为一个 由简单类型组成的类.
这三个类结构如下:
然后是GongWenList类型的代码:
public class GongWenList
{
public GongWenList()
{
m_listGongWen = new List<GongWen>();
}
private IList<GongWen> m_listGongWen;
public IList<GongWen> ListGongWen
{
get { return m_listGongWen; }
set { m_listGongWen = value; }
}
private int m_iItemCount;
public int iItemCount
{
get { return m_iItemCount; }
set { m_iItemCount = value; }
}
}
这样我们的WebService直接返回这样的类型,当然是不能被JS所识别的
于是乎就继承JavaScriptConverter类实现了自己的转换器如下:
public class GongWenListConverter : JavaScriptConverter
{
private IEnumerable<Type> m_supportTypes;
public GongWenListConverter()
{
//
//TODO: 在此处添加构造函数逻辑, typeof(GongWen)
//
this.m_supportTypes = new ReadOnlyCollection<Type>(new Type[] { typeof(GongWenList) });
}
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
throw new NotImplementedException();
}
IDictionary<string, object> result = new Dictionary<string, object>();
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
//if (obj != null)
//{
// GongWenList gongWenList = obj as GongWenList;
// if (gongWenList.Count > 0)
// {
// GongWen[] gongWens = new GongWen[gongWenList.Count];
// for (int i = 0; i < gongWens.Length; i++)
// {
// gongWens[i] = gongWenList[i];
// }
// result["GongWenCollection"] = gongWens;
// result["iItemCount"] = gongWenList.iItemCount;
// }
//}
GongWenList gongwenList = obj as GongWenList;
if (gongwenList.ListGongWen != null)
{
result["GongWenCollection"] = gongwenList.ListGongWen;
}
result["iItemCount"] = gongwenList.iItemCount;
return result;
}
public override IEnumerable<Type> SupportedTypes
{
get { return this.m_supportTypes; }
}
}
转载于:https://www.cnblogs.com/lenther2002/p/4743875.html
利用JavascriptSerializer类 进行Json对象的序列化和反序列化相关推荐
- java将实体类转为json_JavaWeb实体类转为json对象的实现方法
1.创建个实体类 实体类User代码: package com.neuedu.entity; import lombok.AllArgsConstructor; import lombok.Data; ...
- 从零开始学前端:json对象,对象的序列化和反序列化 --- 今天你学习了吗?(JS:Day15)
从零开始学前端:程序猿小白也可以完全掌握!-今天你学习了吗?(JS) 复习:从零开始学前端:字符串.数组的方法 - 今天你学习了吗?(JS:Day12/13/14) 文章目录 从零开始学前端:程序猿小 ...
- js笔记(三)ES5、ES5新增的数组的方法、字符串的方法、字符编码、对象的序列化和反序列化、bind
数组方法.字符串方法总结 大目录 小目录 一.ES5严格模式 1. 严格模式: 2. 严格模式的行为变更: 二.ES5新增的数组的方法 1. 判断是否为数组:Array.isArray(): 2. 判 ...
- Java对象序列化详解6,Java对象的序列化与反序列化详解
把对象转换为字节序列的过程称为对象的序列化,把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种途径: Ⅰ . 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中 Ⅱ. 在网 ...
- Java对象的序列化与反序列化
序列化与反序列化 序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程.一般将一个对象存储至一个储存媒介,例如文件或是内存缓冲区等.在网络传输过程中,可以是字节或是 ...
- java中对象的序列化和反序列化
[对象的序列化和反序列化 ] 1.定义: 序列化--将对象写到一个输出流中.反序列化则是从一个输入流中读取一个对象.类中的成员必须是可序列化的,而且要实现Serializable接口,这样的类的对象才 ...
- Java 对象的序列化和反序列化
当两个进程在进行远程通信时,彼此可以发送各种类型的数据.无论是何种类型的数据,都会以二进制序列的形式在网络上传送.发送方需要把这个Java对象转换为字节序列,才能在网络上传送:接收方则需要把字节序列再 ...
- 对象的序列化与反序列化---IO学习笔记(四)
对象的序列化,反序列化 对象的序列化: 就是将Object转换成byte序列 对象的反序列化: 将byte序列转换成Object 序列化流,反序列化流 序列化流(ObjectOutputStream) ...
- java对象的序列化和反序列化详细解释
java对象的序列化和反序列化是什么意思 1.序列化是干啥用的? 序列化的原本意图是希望对一个Java对象作一下"变换",变成字节序列,这样一来方便持久化存储到磁盘,避免程序运行结 ...
最新文章
- linux删除网卡bond,linux下网卡bond的基本配置及错误
- 【转】 LINQ TO SQL中的selectMany
- 配置防火墙打开 80 端口
- php 分页 url重写 分页问题,解决千古难题,wordpress分页URL问题,wordpress给分页加链接...
- 进行Java Web项目开发需要掌握的技术
- 跳槽想必职场人士都经历过,那么怎么样跳槽才算是跳对了槽呢?
- 【笔试/面试】 —— 最长递增子序列
- 我为什么做程序猿訪谈录
- 编程的未来 Java, C, Go, Swift, Dart? Uncle Bob Martin - The Future of Programming
- Oracle数据库安装教程
- 小程序 微信小商店 获取商品列表
- CS -exe木马分析
- 电脑回收站在哪里?回收站删除的文件怎么恢复?
- 计算机作业攒机单,计算机攒机作业.docx
- cad2011 2010闪退问题
- 1142 Maximal Clique
- Git使用简介一(入门级)
- c语言实现陷波器算法,50Hz数字陷波器的设计.doc
- 从我的角度体会平安车险的服务
- Excel 2010 VBA 入门 031 批量生成上标
热门文章
- 如何用Astra主题免费版建外贸网站
- win10远程连接报错:这可能是由于CredSSP加密数据库修正解决方法
- 高清录屏去噪方法?--QVE屏幕录制
- 大学暗恋一个女同学四年,毕业半年后,同学告诉我她等了我四年。【转贴】
- 测试硬盘读写速度c语言实现,一次解决磁盘IO读取慢全过程实战
- 关于计算机声音说法正确的是,realplayer插件 声音数字化|74数字化声音试题(9)
- 好用的数据备份与恢复软件推荐
- zcmu1074: 求1+1/2+1/3+...+1/n
- dc-dc开关电源的纹波测试
- 账龄分析核对的操作步骤,解决客户不会核对账龄与业务明细的问题