随笔-312  评论-12034  文章-2  trackbacks-256

本文来自《ASP.NET AJAX程序设计 第II卷:客户端Microsoft AJAX Library相关》的第三章《异步调用Web Service和页面中的类方法》,请同时参考本章的其他文章


3.8 XML方式序列化数据

第2章中曾经提到过,ASP.NET AJAX异步通讯层在传递数据时默认采用JSON序列化方式,但同时也提供给我们以XML方式进行序列化的选项。

一般来讲,如果某Web Service方法的返回值类型为XmlDocument或XmlElement的话,我们应该让这类返回值以XML方式进行序列化。例如如下的这个Web Service方法:

[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Xml)]
public XmlDocument GetXmlDocument()
{
    string theString = "<persons>"
        + "<person><name>Tom</name><age>30</age></person>"
        + "<person><name>Jerry</name><age>20</age></person>"
        + "</persons>";
    
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(theString);
 
    return xmlDoc;
}

注意上述代码中的粗体部分,[ScriptMethod(ResponseFormat = ResponseFormat.Xml)]这个属性就将该GetXmlDocument()方法返回值的序列化方式设置为了XML。在客户端的回调函数中,返回的客户端XML文档对象在Visual Studio调试器中显示出的结构如图3-36所示。

图3-36 服务器端XmlDocument类型在客户端的结构

在客户端得到返回的XML文档对象之后,我们即可根据需求对其进行操作,限于篇幅,这里不赘。

对于非XmlDocument或XmlElement的类型,如果我们愿意,也可以选择将其以XML的方式进行序列化。我们还是以前面定义的Employee类为例,如下Web Service方法就以XML序列化的方式返回一个Employee对象:

[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Xml)]
public Employee GetXMLFormatEmployee()
{
    return new Employee(
        12345,
        "Dflying",
        "Dflying@some.com",
        int.MaxValue
    );
}

同样是为该方法应用了[ScriptMethod(ResponseFormat = ResponseFormat.Xml)]属性(代码中粗体部分),在客户端回调函数中,返回的JavaScript对象在Visual Studio调试器中显示出的结构如图3-37所示。

图3-37 以XML方式序列化的Employee对象的结构

可以看到,Employee对象被序列化成了如下XML字符串:

<?xml version="1.0"?>
<Employee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Id>12345</Id>
  <Name>Dflying</Name>
  <Email>Dflying@some.com</Email>
  <Salary>2147483647</Salary>
</Employee>

前面曾经提到过,为某个复杂类型中的某个属性添加[System.Web.Script.Serialization.ScriptIgnore]属性可以让ASP.NET AJAX异步通讯层在自动生成客户端对象时忽略该属性,不过这仅适用于默认的序列化方式,也就是JSON方式。

若希望在XML序列化方式中忽略某复杂对象的某属性,那么我们应该为该属性添加[System.Xml.Serialization.XmlIgnore]属性。我们还是以忽略Employee类中的Salary属性为例,修改Employee类的实现代码:

private int m_salary;
[System.Xml.Serialization.XmlIgnore]
public int Salary
{
    get { return m_salary; }
    set { m_salary = value; }
}

这时我们再次从客户端调用GetXMLFormatEmployee()这个Web Service方法,将会看到Employee对象被序列化成了如下XML字符串,其中没有了<Salary />节点:

<?xml version="1.0"?>
<Employee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Id>12345</Id>
  <Name>Dflying</Name>
  <Email>Dflying@some.com</Email>
</Employee>

若是某个Web Service方法的返回值为字符串类型,且该Web Service方法将使用XML方式序列化返回值,那么该字符串将被默认为是一个XML文档的片段,并已XML方式进行序列化。例如如下Web Service方法:

[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Xml)]
public string GetString()
{
    string theString = "<persons>"
        + "<person><name>Tom</name><age>30</age></person>"
        + "<person><name>Jerry</name><age>20</age></person>"
        + "</persons>";
 
    return theString;
}

在客户端回调函数中,返回的字符串对象在Visual Studio调试器中显示出的结构如图3-38所示,可以看到原本应该是普通字符串的内容被当成了XML片断。

图3-38 普通字符串的内容被默认当成了XML片断处理

当然,ASP.NET AJAX做这样的假设有它的道理,那就是字符串可能实际上表示的就是一段XML数据。但是如果我们需要的就是一个普通的字符串,那么这样做岂不是帮了倒忙吗?

幸运的是,通过在[ScriptMethod]属性中将XmlSerializeString指定为true,我们即可得到普通的字符串,即避免了ASP.NET AJAX为我们做任何的自动转换。让我们按照如下代码修改前面的GetString()方法,注意其中粗体部分:

[WebMethod]
 
[ScriptMethod(ResponseFormat = ResponseFormat.Xml, 
    XmlSerializeString = true)]
public string GetString()
{
    string theString = "<persons>"
        + "<person><name>Tom</name><age>30</age></person>"
        + "<person><name>Jerry</name><age>20</age></person>"
        + "</persons>";
 
    return theString;
}

这时在客户端回调函数中,返回的字符串对象将被自动编码并作为普通字符串传递,如图3-39中高亮部分所示。

图3-39 以XML方式传递普通的字符串数据

 

3.9 小结

ASP.NET AJAX异步通信层为我们在客户端JavaScript中调用服务器端Web Service或ASP.NET页面中的类方法提供了极为便利的基础设施,不但无需掌握任何具体的Ajax实现原理,甚至允许我们在JavaScript中直接用熟悉的、类似C#语言的语法来完成一次与服务器的异步通信。

本章首先借助一个简单的示例程序介绍了在客户端通过ASP.NET AJAX异步通信层调用定义于Web Service中的方法的具体步骤,随后又介绍了从客户端调用定义于ASP.NET页面中的类方法的流程,旨在让读者对ASP.NET AJAX异步通信层为服务器端Web Service及ASP.NET页面中类方法所生成的客户端调用代理有一个初步的认识。

Web应用程序的运行有很多不确定性,从网络状况的不稳定到开发者的粗心大意,任何一个难以预料的问题均会让某次异步调用以失败告终。本章随后通过示例程序介绍了在与服务器进行异步通信时发生异常的处理方法。

为了在异步调用的整个过程中维护必要的状态信息,ASP.NET AJAX所提供的异步调用模型中包含了对传递用户上下文的支持。通过用户上下文对象,我们可以很容易地访问到原始调用函数中的状态。本章也介绍了这部分功能的实现方法。

随后,本章详细介绍了ASP.NET AJAX异步通信层为Web Service生成的客户端异步调用代理的功能,包括调用代理的完整语法、成功/失败回调函数的完整语法以及其他常用的属性和设定。

在使用ASP.NET AJAX异步通信层对Web Service进行异步调用时,默认采用的是HTTP POST方式。但为了提供足够的灵活性,ASP.NET AJAX异步通信层同样允许我们使用HTTP GET进行调用。本章随后就介绍了采用HTTP GET进行调用的方法。

在客户端与服务器端以Ajax方式进行异步交互时,ASP.NET AJAX异步通信层也提供了强大的服务器端.NET类型和客户端JavaScript类型之间自动转换能力,我们只要略加配置,甚至根本不需要任何配置,即可在异步通信的过程中传递包括基本类型、枚举类型、复杂类型、集合(包括泛型集合)类型、数组类型等数据。这是本章中最为重要的内容,因此我们在这部分中给出了大量的示例程序以及详尽的分析,力求阐明传递上述类型的具体方法和注意事项。

ASP.NET AJAX异步通信层在传递数据时默认采用JSON序列化方式,但同时也提供给我们以XML方式进行序列化的选项。本章的最后介绍了让XML作为客户端和服务器端交互时的数据传递格式的方法。

posted on 2007-06-21 08:39 Dflying Chen 阅读(5781) 评论(39)  编辑 收藏 网摘 所属分类: ASP.NET AJAX (Atlas)

评论:
#1楼 2007-06-21 08:58 | Anytao      
哈哈,坐一次沙发,你太多产了,致敬。
  回复  引用  查看    
#2楼 2007-06-21 08:59 | 南疯      
沙发?
在博客园永远没有沙发,大家都在通宵。尤其LZ

  回复  引用  查看    
#3楼[楼主] 2007-06-21 09:04 | Dflying Chen      
@Anytao
谢谢支持:)几天都没有发技术文章了,呵呵

  回复  引用  查看    
#4楼[楼主] 2007-06-21 09:04 | Dflying Chen      
@南疯
呵呵,起得早一点而已,通宵可受不了,要注意身体哦~

  回复  引用  查看    
#5楼 2007-06-21 09:07 | 林_枫      
晕,还是晚了一步。收藏
  回复  引用  查看    
#6楼 2007-06-21 09:07 | GoGoSonny      
有相关Demo或光盘源码放出来吗?
^_^

  回复  引用  查看    
#7楼[楼主] 2007-06-21 09:08 | Dflying Chen      
@林_枫
:)

  回复  引用  查看    
#8楼[楼主] 2007-06-21 09:09 | Dflying Chen      
@GoGoSonny
源代码将在本书出版后放在我的Blog上。稍等几天就好了,谢谢支持!

  回复  引用  查看    
#9楼 2007-06-21 17:28 | MK2      
灌水:总觉得Ajax应该叫Ajaj比较好, 大多数框架都是使用JSON代替XML的...

哈哈, 这系列完了, 期待下一章...

  回复  引用  查看    
#10楼 2007-06-21 20:45 | Leepy      
这章太精彩了,学到了很多!
  回复  引用  查看    
#11楼 2007-06-21 22:54 | 里奥特      
很不错,我似乎想放弃AjaxPro了.!
  回复  引用  查看    
#12楼[楼主] 2007-06-22 10:38 | Dflying Chen      
@MK2
Ajaj没有Ajax那么琅琅上口阿

  回复  引用  查看    
#13楼[楼主] 2007-06-22 10:39 | Dflying Chen      
@Leepy
谢谢

  回复  引用  查看    
#14楼[楼主] 2007-06-22 10:39 | Dflying Chen      
@里奥特
AjaxPro使用起来特别简单,也有很大的优势

  回复  引用  查看    
#15楼 2007-06-22 11:22 | Anthan      
这几天太忙都没有每天读博客,趁着博客园搬家之前赶紧来看看。
这一个系列看下来又学到了不少东西

  回复  引用  查看    
#16楼[楼主] 2007-06-26 09:25 | Dflying Chen      
@Anthan
:)

  回复  引用  查看    
#17楼 2007-06-30 22:22 | JON[未注册用户]
我得到了XML对象如何操作?
  回复  引用    
#18楼 2007-07-03 17:55 | microboat[未注册用户]
请问如何通过ASP.NET AJAX客户端组件上传一个文件?
  回复  引用    
#19楼[楼主] 2007-07-03 20:53 | Dflying Chen      
@JON
任何JavaScript的XML操作方法都可以使用

  回复  引用  查看    
#20楼[楼主] 2007-07-03 20:53 | Dflying Chen      
@microboat
上传文件功能是Ajax无法兼容的。

  回复  引用  查看    
#21楼 2007-07-13 10:57 | winnerzone      
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Xml)]
public XmlDocument GetXmlDocument()
{
string theString = "<persons>"
+ "<person><name>Tom</name><age>30</age></person>"
+ "<person><name>Jerry</name><age>20</age></person>"
+ "</persons>";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(GetString());
return xmlDoc;
}
中的GetString()方法呢?找了半天才发现:theString 没有用进来,是不是要修改下?

  回复  引用  查看    
#22楼[楼主] 2007-07-13 11:10 | Dflying Chen      
@winnerzone
已经修改了,谢谢你帮我指出错误!

  回复  引用  查看    
#23楼 2007-07-13 11:13 | winnerzone      
为什么不把程序写全呢?写个后台调用就完了.....前台的展现也稍微写下吧.从第一篇看到最后一篇,发现最后一篇的缺陷在这里.只写了调试的结果没有写最后展现的结果.和前9篇的书写风格不同了.
  回复  引用  查看    
#24楼[楼主] 2007-07-13 11:34 | Dflying Chen      
@winnerzone
恩,展现比较复杂了,呵呵。在后面几张中有详细介绍

  回复  引用  查看    
#25楼 2007-07-13 14:42 | winnerzone      
你还会把调用Web服务后几张公开吗?比较期待你后面的文章,因为看完了10篇,没有结尾........
  回复  引用  查看    
#26楼[楼主] 2007-07-13 14:49 | Dflying Chen      
@winnerzone
应该已经算是结尾了吧,调用WebService还需要讲些什么呢?觉得这十篇的内容已经基本完整了。

  回复  引用  查看    
#27楼 2007-07-13 15:43 | winnerzone      
我把你的前九篇文章的例子写成了一个项目
http://www.cnblogs.com/winnerzone/archive/2007/07/13/817322.html" target="_new">http://www.cnblogs.com/winnerzone/archive/2007/07/13/817322.html
别介意.提供下载了 .

  回复  引用  查看    
#28楼[楼主] 2007-07-13 19:37 | Dflying Chen      
@winnerzone
没问题,谢谢你的关注和贡献!

  回复  引用  查看    
#29楼 2007-07-17 11:37 | winnerzone      
DflyingChen你有msn吗?我有一个ajax调用web服务的问题.如果光回复问起来比较麻烦.
  回复  引用  查看    
#30楼 2007-07-17 11:38 | winnerzone      
我的msn:winnerzone@126.com
  回复  引用  查看    
#31楼 2007-07-17 11:41 | winnerzone      
直接问你吧.如果有看帖子的朋友会回答我也可以.我现在有一个web服务的站点.我在我的站点里添加了web服务的引用.我如何用ajax调用这个引用中的方法?
  回复  引用  查看    
#32楼 2007-07-17 21:25 | winnerzone      
在你的文章中好像忘了提这么一个问题了.在<asp:ServiceReference Path="http://localhost/service/ServerTime.asmx"" target="_new">http://localhost/service/ServerTime.asmx" /></Services> 这里配置的path属性解释为
The Path property can only point to local Web services. In other words, this property can only point to Web services in the same domain of your Microsoft ASP.NET AJAX application. Path can be a relative, application-relative, domain-relative, or absolute path.

  回复  引用  查看    
#33楼[楼主] 2007-07-17 22:23 | Dflying Chen      
@winnerzone
使用ASP.NET AJAX中引入的asbx文件即可做到,也就是通过服务器段远程Web Service代理来实现。如果需要的话,我可以随后在Blog中把第二卷中的这一章陆续发出来。

  回复  引用  查看    
#34楼[楼主] 2007-07-17 22:24 | Dflying Chen      
@winnerzone
在第一卷和第二卷中的其他章节中都有过说明,所以在这里就没有重复再说一遍:)

  回复  引用  查看    
#35楼 2007-07-18 09:53 | winnerzone      
能今天就将关键内容放出来吗?因为现在项目中非常需要......
  回复  引用  查看    
#36楼[楼主] 2007-07-20 16:03 | Dflying Chen      
@winnerzone
啊?哪部分内容啊?

  回复  引用  查看    
#37楼 2007-09-02 11:41 | lkw[未注册用户]
请教一个问题,一个页面里嵌入了两个IFRAME,一个用来播视频的,一个用AJAX来读取数据的,每1秒读一次,每读一次视频就卡一下,请问这个问题有没有得解决呀。AJAX不是异步通信的吗,为什么读数据会影响到整个页面暂停,请指点一下,语言是用ASP.net2.0
  回复  引用    



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 791272





相关文章:

相关链接: