zoukankan      html  css  js  c++  java
  • 利用JavaScriptSerializer类 进行Json对象的序列化和反序列化和过滤

    项目下载:JavaScriptSerializer_对JSON对象序列化与反序列化及过滤器

    利用<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)

    准备技术:
        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.onload=function()
    {
                var btnGet = $get("btnGet");
    if(btnGet)
    {
                    btnGet.onclick=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} 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);
              }

    复制代码

    具体的前台的脚本就不在给出,通过运行我们会发现反序列化是成功的。

    =================================

    第三篇:

    一个JavaScriptConverter

        事情是这样的,ASP.NET AJAX调用服务器端的代码,返回一个复杂类型,GongWenList,其中GongWenList有两个属性,(1):List<GongWen>类型的ListGongWen,(2)简单的int类型的iItemCount;其中GongWen为一个 由简单类型组成的类.

    这三个类结构如下:


    public class GongWen
        {
    private string m_sSender;
    public string sSender
            {
    get { return m_sSender; }
    set { m_sSender = value; }
            }
    private string m_sBH;
    public string sBH
            {
    get { return m_sBH; }
    set { m_sBH = value; }
            }
    private string m_sHJ;
    public string sHJ
            {
    get { return m_sHJ; }
    set { m_sHJ = value; }
            }
    private string m_sQS;
    public string sQS
            {
    get { return m_sQS; }
    set { m_sQS = value; }
            }
    private string m_sPreSQYH;
    public string sPreSQYH
            {
    get { return m_sPreSQYH; }
    set { m_sPreSQYH = value; }
            }
    private string m_sGWZW;
    public string sGWZW
            {
    get { return m_sGWZW; }
    set { m_sGWZW = value; }
            }
    private string m_sFWZH;
    public string sFWZH
            {
    get { return m_sFWZH; }
    set { m_sFWZH = value; }
            }
    private string m_sItemClass;
    public string sItemClass
            {
    get { return m_sItemClass; }
    set { m_sItemClass = value; }
            }
    private string m_sID;
    public string sID
            {
    get { return m_sID; }
    set { m_sID = value; }
            }
    private string m_sTplType;
    public string sTplType
            {
    get { return m_sTplType; }
    set { m_sTplType = value; }
            }
    private string m_sDateTimeReceived;
    public string sDateTimeReceived
            {
    get { return m_sDateTimeReceived; }
    set { m_sDateTimeReceived = value; }
            }
    public GongWen()
            {
    //
    //TODO: 在此处添加构造函数逻辑
    //
            }
    public GongWen(string sSender, string sBH, string sHJ, string sQS,
    string sPreSQYH, string sGWZH, string sFWZH, string sItemClass,
    string sID, string sTplType, string sDateTimeReceived)
            {
    this.m_sSender = sSender;
    this.m_sBH = sBH;
    this.m_sHJ = sHJ;
    this.m_sQS = sQS;
    this.m_sPreSQYH = sPreSQYH;
    this.m_sGWZW = sGWZH;
    this.m_sFWZH = sFWZH;
    this.m_sItemClass = sItemClass;
    this.m_sID = sID;
    this.m_sTplType = sTplType;
    this.m_sDateTimeReceived = sDateTimeReceived;
            }
        }

    然后是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; }
            }
        }

    复制代码

  • 相关阅读:
    2007年8月小记
    2007年7月小记
    CS2007.1 在多应用程序中的单点登录
    C#类型转换2
    checkbox与说明文字无法对齐的问题
    css中的内容溢出
    javascript获取的层(div)高度
    C#类型转换3
    js修改css样式表解析(转)
    (转)javascript选择id class
  • 原文地址:https://www.cnblogs.com/pingming/p/4049907.html
Copyright © 2011-2022 走看看