使用ASP.NET AJAX异步调用Web Service和页面中的类方法(5):服务器端和客户端数据类型的自动转换:基本类型和枚举类型
本文来自《ASP.NET AJAX程序设计 第II卷:客户端Microsoft AJAX Library相关》的第三章《异步调用Web Service和页面中的类方法》,请同时参考本章的其他文章。
3.7 服务器端和客户端数据类型的自动转换
读到这里,细心的读者可能已经发现了:前面的示例程序中传递给Web Service以及从Web Service返回的数据的类型均为简单的字符串或是整数。可是在实际开发中,只传递字符串或整数类型的数据显然是不够用的。那么ASP.NET AJAX异步通讯层对于服务器端.NET类型和客户端JavaScript类型之间的映射是否提供了一些辅助功能呢?也就是说,在使用ASP.NET AJAX与服务器端进行异步通讯时,我们能不能直接传递诸如DateTime、DataTable乃至更加复杂的自定义类型呢?
答案自然非常令人兴奋——没有任何问题!ASP.NET AJAX异步通讯层提供了强大的服务器端.NET类型和客户端JavaScript类型之间自动转换能力,我们只要略加配置,甚至根本不需要任何配置,即可在异步通讯的过程中传递包括基本类型、枚举类型、复杂类型、集合(包括泛型集合)类型、数组类型等数据。
若是在某些特殊情况下这类自动转换无法满足实际需求,我们需要更为精确地完全控制某个类型的转换规则,那么也不用担心——借助于在ASP.NET AJAX异步通讯层强大的可扩展性,开发者可以容易地实现自己的转换方案,并“插入”到现有ASP.NET AJAX异步通讯层中。关于自定义服务器端和客户端数据类型的转换规则,将在第III卷中详细介绍。
本节就将通过示例程序介绍ASP.NET AJAX异步通讯层所提供的服务器端.NET类型和客户端JavaScript类型之间的自动转换功能。
3.7.1 基本类型
在本节中,基本类型是指数字类型(包括整型、浮点型等)、字符串类型、布尔类型、时间日期类型等。对于这些类型,ASP.NET AJAX异步通讯层能够自动进行服务器端.NET类型和客户端JavaScript类型之间的转换,无须我们任何干预。
例如对于下面的Web Service定义,其中定义了一个名为SendSimpleTypes()的方法,分别接受整型、浮点型、字符串类型、布尔类型、时间日期的六个参数。SendSimpleTypes()方法没有什么实际功能,仅仅起到演示的作用:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class SimpleTypes : System.Web.Services.WebService
{
[WebMethod]
public void SendSimpleTypes(int intVar, float floatVar,
string stringVar, bool boolVar, DateTime datetimeVar)
{
// just for testing
}
}
然后在客户端我们可以分别创建这5种类型,并尝试通过ASP.NET AJAX异步通讯层生成的代理传递到该Web Service中:
var intVar = 123;
var floatVar = 123.456;
var stringVar = "hello, this is Dflying";
var boolVar = true;
var datetimeVar = new Date();
SimpleTypes.SendSimpleTypes(
intVar, floatVar, stringVar, boolVar, datetimeVar
);
在Visual Studio中启动调试功能,在前面定义的Web Service方法SendSimpleTypes()的第一行加上一个断点(如图3-10所示)。
图3-10在Web Service方法的第一行设置断点
当程序运行至SendSimpleTypes()方法时,打开Visual Studio的“Locals”窗口(Ctrl+Alt+V,L)可以看到SendSimpleTypes()方法的5个参数均已被正确地传递到了服务器端。如图3-11所示。
图3-11 在“Locals”窗口中查看局部变量的值
3.7.2 枚举类型
对于枚举类型,若是某个Web Service代理中有所使用(或者Web Service方法接受枚举类型,或者Web Service方法返回枚举类型)的话,ASP.NET AJAX异步通讯层也将自动为该枚举类型生成客户端JavaScript版本,并负责客户端与服务器端类型之间的转换,同样无须我们任何干预。
例如对于如下Web Service以及其中定义的GetTomorrowDay()方法,用来接受一个类型为System.DayOfWeek类型的枚举,然后返回同样类型的枚举,表示下一天是星期几:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class EnumService : System.Web.Services.WebService
{
[WebMethod]
public DayOfWeek GetTomorrowDay(DayOfWeek today)
{
return (DayOfWeek)(((int)today + 1) % 7);
}
}
若是在页面中引入了上面的这个名为EnumService的Web Service代理:
<asp:ScriptManager ID="sm" runat="server">
<Services>
<asp:ServiceReference Path="Services/EnumService.asmx" />
</Services>
</asp:ScriptManager>
然后在页面中书写如下的客户端脚本:
function pageLoad() {
debugger;
}
在Visual Studio中启动调试后,程序将在ASP.NET AJAX客户端框架初始化完毕时(即执行该pageLoad()方法)停下来(debugger语句)。
参考:关于pageLoad()方法以及ASP.NET AJAX客户端框架的初始化过程,将在第4章中详细介绍。关于debugger语句以及ASP.NET AJAX应用程序的调试方法和技巧,将在第III卷中详细介绍。
这是随便打开一个“Watch”窗口(Ctrl+Alt+W,然后数字键1、2、3或者4均可),在其中输入“System.DayOfWeek”并回车确认。随后点击“System.DayOfWeek”一行左边的加号图标展开其中内容,即可看到ASP.NET AJAX异步通讯层自动为该服务器端枚举类型生成客户端枚举类型中的各个属性。如图3-12所示,注意其中从“Sunday”到“Saturday”的7个枚举值。
图3-12 ASP.NET AJAX异步通讯层为
服务器端System.DayOfWeek枚举类型生成的客户端枚举类型
这样,页面中就拥有了服务器端System.DayOfWeek枚举类型的客户端版本。此后,我们也可以将这个客户端的System.DayOfWeek枚举值直接传递给Web Service:
EnumService.GetTomorrowDay(System.DayOfWeek.Monday, onSucceeded);
服务器端将收到“Monday”,当然这个“Monday”已经是服务器端.NET类型的枚举了,如图3-13所示。
图3-13 服务器端收到客户端传递过来的System.DayOfWeek枚举值
随后客户端的回调函数将收到客户端System.DayOfWeek枚举类型的星期二值(“Tuesday”),如图3-14所示。
图3-14 客户端回调函数收到服务器返回的System.DayOfWeek枚举值
对于我们自定义的.NET枚举类型,ASP.NET AJAX异步通讯层同样将一视同仁地生成客户端版本。例如如下表示太阳系八大行星的枚举类型:
namespace Dflying.MyEnums
{
public enum Planets
{
Mercury,
Venus,
Earth,
Mars,
Jupiter,
Saturn,
Uranus,
Neptune
}
}
若是在Web Service方法中用到了的话,例如如下所示的一个Web Service方法,用来随机返回八大行星中的一个:
[WebMethod]
public Planets GetRandomPlanet()
{
Random r = new Random();
return (Planets)((int)r.Next(9));
}
ASP.NET AJAX异步通讯层将为其生成相应的客户端代理。如图3-15所示(同样是在Visual Studio的“Watch”窗口中)。
图3-15 ASP.NET AJAX异步通讯层为服务器端自定义枚举类型生成的客户端枚举类型
总结:想要让ASP.NET AJAX异步通讯层为服务器端枚举类型自动生成相应的客户端枚举类型,并在调用过程中传递并接收该枚举,我们需要:
- 为Web Service类或Web Service中需要暴露给客户端的方法添加[ScriptService]属性;
- 为Web Service中需要暴露给客户端的方法添加[WebMethod]属性;
- Web Service类中的某个方法的某个参数或返回值为该枚举类型;
- 在页面中的ScriptManager控件中添加对该Web Service的引用;
- 在客户端用如下JavaScript语法使用该枚举类型:
[NameSpace].[EnumName].[EnumKey]