2009年07月13日 00:03
3.1 调用Web Service 之所以ASP.NET AJAX将Web Service提高到了如此的重要位置上,让它几乎成为了ASP.NET AJAX服务器端逻辑最受推荐的实现方式,是因为Web Service天生就是纯粹为了业务逻辑而设计的。我们都知道,Web Service没有提供什么“花哨”的用户界面,而是心无旁骛地专注于程序逻辑上的实现,这恰好和ASP.NET AJAX客户端编程模型所倡导的“将表现层和业务逻辑层彻底分开”的理念不谋而合——客户端的ASP.NET AJAX框架用来处理程序所有的界面、与用户交互功能,服务器端则仅仅提供纯粹的数据,不涉及任何表现样式。 借助于ASP.NET AJAX异步通讯层所自动生成的Web Service客户端访问代理,在表现层代码,也就是JavaS 接下来就让我们通过一个简单的示例程序了解一下在ASP.NET AJAX应用程序中使用JavaS 图3-1 用户在界面中输入自己的名字 程序将借助ASP.NET AJAX异步通讯层以Ajax方式把用户的名字发送至服务器端的Web Service。随后该Web Service在服务器端根据用户的名字生成一段问候信息并发送回客户端,客户端收到服务器响应之后,将把这段问候信息显示出来,如图3-2所示。 图3-2 程序显示出来自服务器的问候信息 让我们先从服务器端的Web Service入手。新建一个名为SimpleWebService的Web Service类并在其中声明一个普通的Web Service方法——SayHello()。该方法将接受一个名为name的参数,并生成一条问候信息返回: [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class SimpleWebService : System.Web.Services.WebService { [WebMethod] public string SayHello(string name) { return string.Format("Hello {0}!", name); } } 这就是个普通的Web Service,没有任何不一样之处。注意不要忘记为SayHello()方法添加[WebMethod]属性,这是每个Web方法都必需的。 为了让ASP.NET AJAX生成该Web Service的客户端异步调用代理,进而允许我们在JavaS //………… [ScriptService] //………… public class SimpleWebService : System.Web.Services.WebService { //………… } 提示:我们也可以直接为需要暴露给客户端的Web Service方法添加[ScriptService]属性,而不必将其添加到Web Service类上。 [ScriptService]属性位于System.Web.Script.Services命名空间中,如果需要的话,还要添加如下的using语句: using System.Web.Script.Services; 下面列出完整的SimpleWebService Web Service代码如下,注意其中粗体部分: using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; using System.Web.Script.Services; [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [ScriptService] public class SimpleWebService : System.Web.Services.WebService { [WebMethod] public string SayHello(string name) { return string.Format("Hello {0}!", name); } } 完成了Web Service编写之后,我们来先行测试一下——开发过程中不断地进行阶段性测试有助于尽快发现潜在的问题,并将其扼杀在萌芽中。如果一切顺利的话,那么测试该Web Service时可以看到如图3-3所示的结果。 图3-3 测试Web Service时的界面 接下来即可用ASP.NET AJAX异步调用这个Web Service了。首先新建一个ASP.NET页面。当然,该页面所在的Web站点必须已经配置好了ASP.NET AJAX的支持,详细配置方法请参考本书第I卷。在该页面上添加一个ScriptManager服务器端控件,这是每一个ASP.NET AJAX应用程序都必不可少的: <asp:ScriptManager ID="sm" runat="server"> </asp:ScriptManager> 为了让ASP.NET AJAX为前面的Web Service生成客户端异步调用代理,我们需要在ScriptManager控件中添加该Web Service的引用: <asp:ScriptManager ID="sm" runat="server"> <Services> <asp:ServiceReference Path="Services/SimpleWebService.asmx" /> </Services> </asp:ScriptManager> 这种声明语法隐约中传递了这样的含义:Web Service的客户端异步调用代理脚本将由ScriptManager控件管理——这非常自然,不是么?ScriptManager就是用来管理(manage)脚本(script)的呀!关于<Services />标签以及<asp:ServiceReference />标签的详细使用方法,在本书第I卷中已经有详细讨论,这里不赘。 随后声明程序界面中必不可少的UI元素: <input id="tbName" type="text" /> <input id="btnInvoke" type="button" value="Say Hello" on <div id="result"></div> 其中id为tbName的<input />作为文本框,用来让用户输入名字;id为btnInvoke的<input />作为按钮,点击将触发异步调用Web Service;id为result的<div />则用来将Web Service返回的问候内容显示出来。这些id均将在稍后用到。 上面代码中btnInvoke按钮定义了click事件的事件处理函数,该函数的实现如下。注意这是客户端JavaS function btnInvoke_on var theName = $get("tbName").value; SimpleWebService.SayHello(theName, on } 首先用$get("tbName").value取得了用户在文本框中输入的文字。然后第二句SimpleWebService.SayHello()即调用了ASP.NET AJAX异步通讯层自动为SimpleWebService生成的客户端代理。这是本示例程序中最为重要的一句——与用C#在Web Service中声明的SayHello()方法签名相比,其参数个数以及顺序均完全一样,甚至调用语法也没什么特别——都是[NameSpace].[ClassName].[MethodName](param1, param2 …, callbackFunction)。由此我们能够看出ASP.NET AJAX异步通讯层为降低开发者学习曲线、提高开发者生产效率所做出的努力及良苦用心。 参考:关于用来取得DOM元素引用的$get()方法,请参考本卷第1章中的介绍。 不过客户端代理还提供了额外的一个参数——异步调用的回调函数名称,这里为on function on $get("result").innerHTML = result; } on 参考:ASP.NET AJAX异步通讯层为Web Service自动生成的客户端代理以及相应的回调函数还提供了更多的参数和配置功能,这些都将在本章中详细介绍。 这样就完成了本示例程序的所有代码编写。运行该程序,如果一切顺利的话,你将看到如图3-1和图3-2所示的界面。 ASP.NET AJAX的异步通讯层在本示例程序中小试牛刀,纵观整个示例程序的实现代码,我们不难看出该架构的强大功能以及为我们开发者细心周全的考虑。虽然在实际开发中,我们很难遇到本示例程序中这样简单的功能。但麻雀虽小,五脏俱全,理解了这样一个简单的示例程序之后,我们完全可以举一反三,根据开发过程中的实际需要编写不同的Web Service以及客户端调用代码,轻松地完成工作。 总结:想要使用ASP.NET AJAX在客户端JavaS
3.2 调用页面中的类方法 让客户端JavaS protected void Button1_Click(object sender, EventArgs e) { myLabel.Text = this.GetTextForLabel(); } public string GetTextForLabel() { // ...... return "Some Text"; } 对于那些“遗留”的ASP.NET应用程序来讲,这样直接定义在ASP.NET页面中的方法更是相当常见。若是仅仅为了配合ASP.NET AJAX的客户端访问Web Service功能,就将这些方法一一迁移到Web Service中,岂不是非常麻烦? 好在ASP.NET AJAX在设计时考虑到了这个问题,并提供给我们一种作为替代的选择。ASP.NET AJAX异步通讯层能够将声明在ASP.NET页面中的公有的类方法(C#中的static,VB.NET中的Shared)当作Web Service中声明的方法一样对待,为其生成类似的客户端调用代理。 我们还是通过一个实例程序来了解这个功能。该示例程序的功能与界面均与前面一节中的完全一致,唯一的不同就是,客户端异步调用的不再是某个Web Service,而是定义在ASP.NET页面中的类方法。 首先是定义在ASP.NET页面中的类方法,完整的方法声明如下: [WebMethod] public static string SayHelloFromPage(string name) { return string.Format("Hello {0}!", name); } 特别需要注意的是,若要让ASP.NET AJAX为其生成客户端调用代理,那么一定要为该方法添加[WebMethod]属性。 然后是ScriptManager控件,注意粗体部分代码设置了EnablePageMethods属性为true,这也是让客户端能够直接调用服务器端页面方法所必需的。若你忘记了设定该属性,那么程序将无法完成预期功能: <asp:ScriptManager ID="sm" EnablePageMethods="true" runat="server" /> 程序界面中的UI元素和前一个节中的示例程序完全一致,这里不赘: <input id="tbName" type="text" /> <input id="btnInvoke" type="button" value="Say Hello" on <div id="result"></div> 而本示例程序中按钮的click事件处理函数以及异步调用的回调函数则需要一定的修改,如下所示: function btnInvoke_on var theName = $get("tbName").value; PageMethods.SayHelloFromPage(theName, on } function on $get("result").innerHTML = result; } 注意上述代码中的粗体部分。可以看到,调用页面方法代理时统一的前缀为PageMethods。接下来是页面方法的名称,这里为SayHelloFromPage(),其参数列表和C#中方法的定义一致,额外的一个参数表示本次异步调用的回调函数。即语法为: PageMethods.[MethodName](param1, param2 …, callbackFunction); 这样即完成了本示例程序,运行一下,我们将会看到如图3-1和图3-2一样的界面。 总结:想要使用ASP.NET AJAX在客户端JavaS
|