使用ASP.NET AJAX异步调用Web Service和页面中的类方法(10):服务器端和客户端数据类型的自动转换:以XML方式序列化数据、小结

本文来自《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  阅读(10331)  评论(37编辑  收藏  举报