准备技术:
    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}\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);
          }

具体的前台的脚本就不在给出,通过运行我们会发现反序列化是成功的。
程序下载地址:http://files.cnblogs.com/henllyee/JavascriptConverter.rar

转载于:https://www.cnblogs.com/Henllyee/archive/2008/07/18/1246161.html

Asp.net Ajax WebService 实现循环引用(自定义JavascriptConverter)相关推荐

  1. c ajax 调用webservice,Asp.net Ajax WebService 实现循环引用(自定义JavascriptC

    准备技术: 1.简单的WebService编写: 2.了解Asp.net Ajax 客户端访问WebService 内容: asp.net ajax框架在去年看过,只是些基本的使用,并没有过多的去研究 ...

  2. EXT调用ASP.NET AJAX WebService

    在asp.net ajax中,使客户端调用WebService变得非常的简单,而且非常有用(个人觉得这个功能是asp.net ajax的核心,很多与客户端的交互都需要个功能来辅助实现).那在EXT中, ...

  3. [导入]ASP.NET AJAX 说明文档-客户端引用-全局命名空间-JavaScript 基础类型扩展-Array 类型扩展-add 函数...

    Array.add 函数.将元素添加到 Array 的结尾处. 本函数是静态函数,使用时无需实例化.语法Array.add(array, 文章来源:http://blog.csdn.net/chswo ...

  4. [导入]ASP.NET AJAX 说明文档-客户端引用-全局命名空间-JavaScript 基础类型扩展-Array 类型扩展-contains 函数...

    Array.contains 函数.使用 contains 函数确定某元素是否在 Array 中.在Firefox浏览器中 调用 contains 函数 如果数组中有元素被设置为 undefined且 ...

  5. 在ASP.NET AJAX中使用应用程序服务和本地化(5):自定义应用程序服务的服务器端实现...

    本文来自<ASP.NET AJAX程序设计 第II卷:客户端Microsoft AJAX Library相关>的第五章<应用程序服务和本地化>. 身份认证与用户个性化等应用程序 ...

  6. nstimer循环引用_解决NSTimer循环引用导致内存泄漏的六种方法

    demo放在了GitHub 内存泄漏的原因: self强引用timer.timer添加在runloop上,只要timer不销毁self就销毁不了.当然了你可以选择在viewWillDisappear中 ...

  7. asp.net AJAX 使用webServices调用时,出现“WebService”未定义

    首先继续鄙视一下坑爹的asp.net,对自己的无知继续表示极度的无语 一个非常简单的在ajax中的web service调用 首先取一个自定义的web services备用 [WebService(N ...

  8. 关于在Webservice里使用LinqToSQL遇到一对多关系的父子表中子表需要ToList输出泛型而产生循环引用错误的解决办法!(转)...

    做一个网站时,有2个表,是一对多的关系 然后用生成器自动生成了一个LINQ To SQL类,然后查询子表时 由于子表里也有个父表的属性,所以当把查询的结果ToList时 又通过Webservice输出 ...

  9. 关于在Webservice里使用LinqToSQL遇到一对多关系的父子表中子表需要ToList输出泛型而产生循环引用错误的解决办法!...

    做一个网站时,有2个表,是一对多的关系 然后用生成器自动生成了一个LINQ To SQL类,然后查询子表时 由于子表里也有个父表的属性,所以当把查询的结果ToList时 又通过Webservice输出 ...

最新文章

  1. 脑细胞膜等效神经网路12分类实例
  2. mysql调试索引_10 分钟让你明白 MySQL 是如何利用索引的?
  3. 学习Python必须要会的,在字符串,列表,元组三者之间相互转换的方法
  4. python中cv2库_Python cv2库(人脸检测)
  5. php冒泡和选择排序,选择排序vs冒泡排序
  6. django19:项目开发流程
  7. 弹射王服务器正在维护中,《弹射王》IOS版合服公告-1.7
  8. mac下hive-2.2.0-src版本的编译
  9. 各种边缘检测算子特点比较(canny)
  10. dell网卡linux驱动,Dell R720上安装linux网卡驱动
  11. steam游戏直连工具
  12. js实现canvas在线画板
  13. BeatSaber节奏光剑双手柄MR教程
  14. Linux搭建测试环境步骤
  15. 微信公众平台登录 超详解 Springboot版
  16. 甘特图:有效的项目管理计划怎么制定?
  17. 【FND】EBS中Java并发程序开发
  18. 畅捷通T+Cloud给客户一站式的产品体验
  19. 华为nova10和荣耀70哪个值得买 哪个性能更好
  20. JS实现限制可移动div的移动范围

热门文章

  1. LabVIEW CompactRIO 开发指南2 CompactRIO软件架构
  2. 大型机、小型机、x86服务器的区别
  3. 创建LVM逻辑卷并挂载
  4. 【读后感】让创新野蛮生长
  5. python经典小游戏五子棋,适合python编程的小游戏
  6. 【prompt】什么是 Soft Prompt 和 Hard Prompt ?
  7. 51单片机数控电源c语言设计,基于51单片机的数控电源
  8. 简观《非常24小时》
  9. 查询网址 连接虚拟机,vi编辑开启ens33网络
  10. 公司注册网站有哪些流程呢?