决战.NET
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

4.3 与Web Services结合

除了使用PageMethods输出静态函数供JavaScript调用外,ASP.NET AJAX也支持由JavaScript调用Web Service。用法很简单,只要在欲输出的Web Service类上标示ScriptService Attribute,再于ScriptManager的Services属性中设定URL即可。请依以下的步骤做。

1. 建立一个Web Service,命名为HelloService.asmx。

2. 在HelloService类中键入程序4-8的代码。

3. 建立一个新网页,命名为CallWebService.aspx。

4. 在页面上放入ScriptManager控件。

5. 在ScriptManager控件的Services属性窗中添加一个Service,如图4-3所示。

true

图4-3

6. 在网页的源码中键入程序4-9粗体字部分。

程序4-8

    Samples\4\AjaxDemo2\App_Code\HelloService.cs
    using System;
    using System.Web;
    using System.Collections;
    using System.Web.Services;
    using System.Web.Services.Protocols;
    /// <summary>
    /// Summary description for HelloService
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.Web.Script.Services.ScriptService]
    public class HelloService : System.Web.Services.WebService {
          public HelloService () {
            //Uncomment the following line if using designed components
            //InitializeComponent();
        }
        [WebMethod]
        public string Hello(string name) {
            return string.Format("Hello {0}",name);
        }
    }

程序4-9

    Samples\4\AjaxDemo2\CallWebServcie.aspx
    <%@ Page Language="C#" AutoEventWireup="true"
    CodeFile="CallWebService.aspx.cs"
    Inherits="CallWebService" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
    </head>
    <body>
          <form id="form1" runat="server">
          <div>
            <asp:ScriptManager ID="ScriptManager1" runat="server">
                <Services>
                    <asp:ServiceReference Path="HelloService.asmx" />
                    <asp:ServiceReference Path="ZipServiceProxy.asmx" />
                </Services>
            </asp:ScriptManager>
            <script language=javascript>
            function CallService()
            {
              var txt = $get('Text1');
              HelloService.Hello(txt.value,SucceededCallback);
            }
            function SucceededCallback(result)
            {
                alert(result);
            }
            </script>
          </div>
              <input id="Text1" type="text" />
              <input id="Button1" type="button" value="call" onclick=
                "CallService();" />/>
          </form>
    </body>
    </html>

完成后执行程序,点击call按钮,便可看到如图4-4所示的结果。

true

图4-4

这是如何办到的呢?先看程序4-9 中JavaScript的CallService函数,此函数调用了Hello-Service.Hello函数,HelloService对应了我们刚建立的HelloService.asmx这个Web Service,Visual Studio 2005建立Web Service时默认是不会加上任何namespace声明的,所以这里直接以<Web Service类名>.<函数名>便可调用Web Servcie,当你为Web Service类加上namespace之后,调用方式就得变成<namespace>.<Web Service类名>.<函数名>。JavaScript调用对应的Web Service函数时,除了传入该函数所需要的参数外(本例是name,字符串类型),还得传入另一个接收结果的函数(本例是OnSucceededCallback函数),这是因为ASP.NET AJAX调用Web Servcie时采用异步的方式调用,当调用完成后,便会调用所传入的接收结果函数,并传入传回值。OK,那ASP.NET AJAX是如何调用Web Service的呢?简单地说,ASP.NET AJAX替换了Web Service原有的处理机制,加上了一个特殊的参数/jsdebug,如果你在浏览器上键入Web Service的URL并加上/jsdebug参数时,就会得到ASP.NET AJAX为此Web Service所产生出来的Proxy程序文件,如图4-5所示。

true

图4-5

这个Proxy程序文件中声明了HelloService.Hello函数,并在此函数中利用ASP.NET AJAX Client Framework所提供的WebServiceProxy对象调用这个Web Service。在调用Web Service时,也可以像调用PageMethods时那样设定Timeout及错误处理机制,如程序4-10所示。

程序4-10

    Samples\4\AjaxDemo2\CallWebServcie.aspx
    function CallService()
    {
          var txt = $get('Text1');
          HelloService.set_timeout(5000);
          HelloService.Hello(txt.value,SucceededCallback,FailedCallback);
    }
    function SucceededCallback(result)
    {
        alert(result);
    }
    function FailedCallback(error)
    {
        alert("Call Service Error:"+error.get_message());
    }

对Web Service有兴趣的读者或许会问一个问题,那就是在ASP.NET AJAX中,可否调用外部的Web Service呢?也就是于Service中将Path设为外部的网站,答案是可以的!不过有几个限制:第一、该Web Servcie必须也是以ASP.NET建立的,而且必须标示为ScriptService。二、受限于XMLHttpRequest不允许跨网域调用的限制,使用者必须调整浏览器的安全设定。第二个限制是比较麻烦且难以说服使用者的,所以最好的方式是自己建立一个Web Service,在此Web Service中串接外部的Web Service,这样不仅可以调用非ASP.NET所建立的Web Servcie,而且不受XMLHttpRequest不能跨网域的限制。

PageMethods与Web Service

在早期未Release的Atlas Framework中,并未要求PageMethods以静态函数类型声明,这使得每次Client端调用PageMethods时,都得经过传统的ASP.NET页面处理流程,因此让PageMethods背上效率不高的恶名。在ASP.NET AJAX正式版推出后,要求PageMethods一定得是静态函数,原因就是要绕过传统的ASP.NET页面处理流程,所以在ASP.NET AJAX正式版中,PageMethods已经与Web Service的性能不相上下了。另外,ASP.NET AJAX正式版中,你甚至可以将PageMethods当Web Servcie用,只要在ScriptManager控件的Services属性窗上添加Service时,将其Path设定为提供PageMethods的那个.aspx文件即可。