除了允许 Web Method 接受 HTTP GET 请求之外,在需要从某个服务而非 JSON 返回 XML 响应时也可使用ScriptMethod 属性。例如,某个 Web 服务可能从远程站点检索到一个RSS 反馈,并将其作为一个 XmlDocument 或 XmlElement 对象返回,然后客户端上就可以进行XML 数据处理。
程序列表 7 的示例是使用ResponseFormat属性指定应从Web Method 返回的XML 数据。
程序列表7.使用带有ResponseFormat属性的ScriptMethod属性
[WebMethod] [ScriptMethod(ResponseFormat = ResponseFormat.Xml)] public XmlElement GetRssFeed(string url) { XmlDocument doc = new XmlDocument(); doc.Load(url); return doc.DocumentElement; }
ResponseFormat也可与XmlSerializeString属性一起使用。XmlSerializeString属性有一个默认值false,表示当 ResponseFormat属性设为 ResponseFormat.Xml时,除从 Web Method 返回的字符串之外的所有返回类型都被序列化为 XML。当XmlSerializeString 设为 true 时,从 Web Method 返回的所有类型,包括字符串类型,都被序列化为XML。如果ResponseFormat 属性的值为 ResponseFormat.Json,则 XmlSerializeString 属性将被忽略。
程序列表 8 的示例是使用XmlSerializeString属性强制将字符串序列化为XML。
程序列表8.使用带有XmlSerializeString属性的ScriptMethod属性
[WebMethod] [ScriptMethod(ResponseFormat = ResponseFormat.Xml,XmlSerializeString=true)] public string GetXmlString(string input) { return input; }调用程序列表 8 中的 GetXmlString Web Method,将返回如下所示的值:
尽管默认的 JSON 格式使请求和响应的总规模降到最小,并更方便为ASP.NET AJAX 客户端以跨浏览器方式使用,但当 Internet Explorer 5或更高版本等客户端应用程序需要从 Web Method 返回XML 数据时,也可以使用ResponseFormat和XmlSerializeString属性。
使用复杂类型在程序列表 5 的示例中,从 Web 服务返回了一个名为 Customer 的复杂类型。Customer 类在内部将几个不同的简单类型定义为FirstName 和 LastName 等属性。在启用了 AJAX 的 Web Method 上使用作为输入参数或返回类型的复杂类型发送到客户端之前,它们自动被序列化为JSON 格式。但嵌套(在另一个类型内部定义)的复杂类型默认情况下未作为独立的对象提供给客户端使用。
当某个 Web 服务使用的嵌套复杂类型也需要在客户端页面中使用时,可以向此Web 服务添加ASP.NET AJAX GenerateScriptType 属性。例如,程序列表 9 中的 CustomerDetails 类就包含了表示嵌套复杂类型的Address 和 Gender 属性。
程序列表9.此处的CustomerDetails类包含两个嵌套复杂类型
public class CustomerDetails : Customer { public CustomerDetails() { } Address _Address; Gender _Gender = Gender.Unknown; public Address Address { get { return _Address; } set { _Address = value; } } public Gender Gender { get { return _Gender; } set { _Gender = value; } } }程序列表 9 中的 CustomerDetails类中定义的Address 和Gender 对象不会自动在客户端侧通过JavaScript 使用,因为它们是嵌套类型(Address 是类,Gender 是枚举)。如果某个在Web 服务中使用的嵌套类型必须供客户端侧使用,那么可以使用前面提到过的GenerateScriptType属性(参见程序列表 10)。如果从服务返回不同的嵌套复杂类型,可以多次添加此属性。此属性可以直接应用于Web 服务类或上述特定 Web Method。
程序列表10.使用GenerateScriptService属性定义应提供给客户端使用的嵌套类型。
[System.Web.Script.Services.ScriptService] [System.Web.Script.Services.GenerateScriptType(typeof(Address))] [System.Web.Script.Services.GenerateScriptType(typeof(Gender))] [WebService(Namespace = "")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class NestedComplexTypeService : System.Web.Services.WebService { //Web Methods }
通过将 GenerateScriptType属性应用于 Web 服务,Address 和 Gender 类型将自动为客户端侧的ASP.NET AJAX JavaScript 代码所用。程序列表 11 中所示的示例是通过向一个 Web 服务添加GenerateScriptType属性自动生成 JavaScript 并被发送至客户端。本文档稍后将演示如何使用嵌套复杂类型。
程序列表11.在ASP.NET AJAX页面中提供嵌套复杂类型
if (typeof(Model.Address) === 'undefined') { Model.Address=gtc("Model.Address"); Model.Address.registerClass('Model.Address'); } Model.Gender = function() { throw Error.invalidOperation(); } Model.Gender.prototype = {Unknown: 0,Male: 1,Female: 2} Model.Gender.registerEnum('Model.Gender', true);
调用标准 Web 服务(.NET 或其他平台)通常涉及到创建一个代理对象,将您从发送 SOAP 请求和响应消息的复杂事务中屏蔽。使用ASP.NET AJAX Web 服务调用,可以轻松地创建和使用JavaScript 代理,以便轻松调用服务而无需考虑序列化及反序列化JSON 消息。通过使用 ASP.NET AJAX ScriptManager 控件,可以自动生成JavaScript 代理。
创建能调用 Web 服务的 JavaScript 代理是通过ScriptManager 的Services 属性完成的。通过此属性,可以定义一个或多个能为ASP.NET AJAX 页面异步调用、以便发送或接收数据而无需回传操作的服务。通过使用ASP.NET AJAX ServiceReference 控件并指定到控件的Path 属性的 Web 服务 URL 来定义服务。程序列表 12 中的示例是引用一个名为CustomersService.asmx 的服务。
<asp:ScriptManager ID="ScriptManager1" runat="server"> <Services> <asp:ServiceReference Path="~/CustomersService.asmx" /> </Services> </asp:ScriptManager>
程序列表12.定义在ASP.NET AJAX页面使用的 Web服务