深入Atlas系列:Web Sevices Access in Atlas(6) - 对于复杂数据类型的支持(下)

简介:
 在上一篇文章中,我们提到了 Atlas在将一个Dictionary转换为一个对象时,会调用对应的IJavaScriptSerializationContext对象的 GetType(string)方法,以获得“真正”的目标对象类型。在Atlas对于Web Services方法的Request所引起的转换过程中,这个IJavaScriptSerializationContext对象是一个 WebServiceData类的实例,它的GetType方法会在对应的那个Web Services类中寻找相关的数据类型。那么Atlas是如何寻找这些类型的呢?什么样的类型会被查找到呢?

  通过查看代码,我们可 以发现,WebServiceData.GetType(string)方法其实是返回它的一个叫做_clientTypesDictionary的实例 变量中保存的Type。WebServiceData._clientTypesDictionary在第一被使用之前会被初始化。我们在这里略过了各个 方法之间的调用,直接查看真正初始化该变量的方法:WebServiceData.ProcessClientTypes方法。代码如下:
 ProcessClientTypes()方法分析

  代码很容易理解,通过枚举每一个方法的每一个参数加以处理,最后还要处理返回值类型。在这里有一个相当重要的方法,就是通过ProcessClientType(Type, bool)加载可识别的参数类型,我们来看一下它的代码:
 ProcessClientType(Type, bool)方法分析

  标记完可以处理的类型后,还会递归的将该类型相关的所有类型做处理。例如数组的元素和属性的类型。值得注意的是,在递归处理该类型相关的类型时,只会处理具有set方法的属性,而不会处理公有实例成员变量的类型,这也就解释了在之前的文章《 深入Atlas系列:Web Sevices Access in Atlas(4) - 对于复杂数据类型的支持(上) 》 中问题4所遇到的类型无法找到的错误。奇怪的是,在反序列化的对象之后恢复对象信息时也为实例的成员变量设值,因此个人认为,这是Atlas的一个“失 误”。因此对于作为实例成员变量的类型,除非它也直接作为Web Services方法参数出现过,否则就无法被找到了。但是个人建议,在为Atlas创建Web Services方法的参数类型时,尽量完全使用属性,而不是成员变量。

  不过这样的话,仅仅只有Web Services方法参数,以及相关的类型才能在反序列化的时候被使用到,这样似乎也够用了。不过Atlas的能力还远不止这些。Atlas能够将任意的 类型附加在Web Services类中,使该类型能够在反序列化过程中被找到。这就是ProcessXmlIncludeAttributes方法的功能,可以看到,它在 ProcessClientType()方法中被调用了。我们来看一下它的代码:
 ProcessXmlIncludeAttributes方法分析

  代码非常简单,就不多加解释了。可以看出,原本用来辅助XmlSerialiaer的XmlIncludeAttribute被用在这里了! 这的确是一个好消息,于是我们就能通过为一个方法标记XmlIncludeAttribute来为一个Web Services添加额外支持的数据类型,例如:
[XmlInclude( typeof (AdditionalType))]

  有了这个功能,就为Atlas访问Web Services方法的功能增色了不少。在以后将会有相关示例来演示XmlIncludeAttribute的有用之处。



   到上面为止,从客户端序列化一个对象,到服务器端将Web Services方法的参数生成的整个过程已经讨论完了,也就是说Atlas访问Web Services方法的大部分的实现方式已经分析结束了。下面的做法自然是使用反射机制调用Web Services方法,然后再将所得的结果对象进行JSON序列化输出(Xml序列化输出非常常见,因此在这里不作讨论)。将结果序列化的功能是调用 Microsoft.Web.Script.Serialization.JavaScriptObjectSerializer的静态方法 Serialize(object,IJavaScriptSerializationContext)工作的,不过真正进行序列化工作的是 Microsoft.Web.Script.Serialization.JavaScriptObjectSerializer类的实例方法 SerializeValue。很自然,在构造JavaScriptObjectSerializer的时候传入的 IJavaScriptSerializationContext对象为当前的WebServiceData。我们来看一下SerializeValue 方法的实现:
 SerializeValue方法分析

  如果我们在Web.config里配置了与该类型对应的JavaScriptConverter(详细信息请见之前的文章《 深入Atlas系列:Web Sevices Access in Atlas(5) - 对于复杂数据类型的支持(中) 》), 那么就会调用相应JavaScriptConverter对象的SerializeObject方法进行对象的序列化操作,这就是之前谈到的自定义对象序 列化和反序列化功能的体现。在之后的文章里我将提供相应的示例来具体解释如何通过继承JavaScriptConverter来对Atlas进行扩展,在 某些时候这样的扩展还是相当有必要的,特别是在使用复杂类型的时候。

  在这里,我们只关注Atlas提供的内部序列化对象的方法。因此来看一下SerializeValueInternal方法的实现。代码如下:
 SerializeValueInternal方法

  企图对于如此清晰的代码作任何过多的解释似乎都是愚蠢的行为。需要注意的地方似乎只有在序列化中会对循环的引用进行侦测,如果发现已经被序列 化过的代码又需要序列化了则会抛出InvalidOperationException。不过对于复杂对象,这个似乎是无法避免的,在之后的文章里我将提 供示例来说明如何使用继承JavaScriptConveter来提供对于复杂类型的自定义序列化以及反序列化的方式,正如Atlas中为 DataSet,DataTable和DataRow定义这种扩展一样。

  在上面这个方法中,SerializeDictionary和SerializeEnumerable的实现都非常简单,只是将对象序列化成JSON形式的“{}”或“{}”而已。我们在这里只关注SerializeCustomObject方法的实现,代码如下:
 SerializeCustomObject方法分析

  通过代码可以看到,在序列化一个对象时对略过使用了XmlIgnoreAttribute标记的成员变量或属性,在开发时可以利用这一点。其余的似乎都没有什么可说的了。



   就这样,Atlas调用Web Service方法对于复杂类型支持的代码就全部分析完了。代码可能虽然有点多,但是其逻辑还是相当清晰的,也提供了非常强大的自定义方式以供扩展。在这 篇文章之后,我将会提供几个示例来说明“深入Atlas系列:Web Sevices Access in Atlas(6) - 对于复杂数据类型的支持”三篇文章里所提到的功能,希望对大家有用。另外,如果有朋友看了这些文章有任何感想和使用技巧的话,欢迎和我进行讨论,本人不胜 感激。:)


本文转自 jeffz 51CTO博客,原文链接:http://blog.51cto.com/jeffz/60800,如需转载请自行联系原作者

目录
打赏
0
0
0
0
265
分享
相关文章
Go 语言学习指南:变量、循环、函数、数据类型、Web 框架等全面解析
掌握 Go 语言的常见概念,如变量、循环、条件语句、函数、数据类型等等。深入了解 Go 基础知识的好起点是查阅 Go 官方文档
961 2
Web 前端大揭秘!JS 数据类型检测竟如此震撼,一场惊心动魄的代码探秘之旅等你来!
【8月更文挑战第23天】在Web前端开发中,合理检测数据类型至关重要。JavaScript作为动态类型语言,变量类型可在运行时变化,因此掌握检测技巧十分必要。
60 1
Web前端的奇幻之旅:探索JS数据类型的奥秘与差异
【8月更文挑战第23天】JavaScript是一种动态类型语言,提供多种内置数据类型支持信息的存储与操作。这些类型对Web前端开发者至关重要,直接影响代码性能与可读性。JavaScript数据类型主要分为两大类:原始数据类型(如Undefined、Null、Boolean等)与引用数据类型(如Object、Array等)。原始类型直接存储值,而引用类型存储指向数据的引用。原始类型不可变且存储在栈中,访问更快;引用类型则存储在堆中,可通过其引用进行修改。理解这些差异有助于编写高效、可维护的代码。
66 0
idea 调试报错 Illegal access: this web application instance has been stopped already.
idea 调试报错 Illegal access: this web application instance has been stopped already.
213 0
【Web 前端】TypeScript 的内置数据类型有哪些?
【5月更文挑战第1天】【Web 前端】TypeScript 的内置数据类型有哪些?
【Web 前端】JS数据类型有哪些?区别?
【4月更文挑战第22天】【Web 前端】JS数据类型有哪些?区别?
【Web 前端】JS中检测数据类型的有哪些?
【4月更文挑战第22天】【Web 前端】JS中检测数据类型的有哪些?
Tomcat【部署 02】Web端403 Access Denied You are not authorized to view this page解决方法(Tomcat 10.2.12 版本)
Tomcat【部署 02】Web端403 Access Denied You are not authorized to view this page解决方法(Tomcat 10.2.12 版本)
879 0
ajax中get和post的区别,datatype返回的数据类型有哪些?web开发中数据提交的几种方式,有什么区别。百度使用哪种方式?
ajax中get和post的区别,datatype返回的数据类型有哪些?web开发中数据提交的几种方式,有什么区别。百度使用哪种方式?
79 0
web前端-JavaScript标识符和数据类型/强制类型转换
web前端-JavaScript标识符和数据类型/强制类型转换
150 0

热门文章

最新文章