通过 ScriptManager 控件添加一个指向CustomersService.asmx的引用,将动态生成一个 JavaScript 代理并为页面所引用。使用<script> 标记嵌入代理,且通过调用CustomersService.asmx 文件和向其末尾添加 /js 动态载入它。下例演示了web.config 中禁用了调试时如何在页面嵌入JavaScript 代理:
<script src="CustomersService.asmx/js" type="text/javascript"></script>
注意:如果您想查看实际生成的 JavaScript代理的代码,可以在Internet Explorer的地址栏输入相应的.NET Web服务的URL,并在其末尾添加/js。
如果 web.config 中启用了调试,页面中将嵌入 JavaScript 代理的调试版本,如下所示:
<script src="CustomersService.asmx/jsdebug" type="text/javascript"></script>
ScriptManager 创建的 JavaScript 代理也可不使用<script>标记的src 属性引用,而是直接嵌入页面。操作方法为:将 ServiceReference控件的 InlineScript 属性设为 true(默认值为 false)。当代理未跨页面共享、且您希望减少对服务器的网络调用数量时,可以采用这一方法。InlineScript 被设为 true 时,浏览器不会缓存代理脚本。因此如果代理被一个ASP.NET AJAX 应用程序中的多个页面使用,建议将InlineScript 设为 default。使用 InlineScript 属性的示例如下:
<asp:ServiceReference InlineScript="true" Path="~/CustomersService.asmx"/>
使用 JavaScript 代理一旦ASP.NET AJAX 页面使用 ScriptManager 控件引用某个Web 服务,便可发起对此Web 服务的调用,返回的数据可以使用回调函数处理。 Web 服务的调用通过引用其命名空间(如果有的话)、类名称和 Web Method 名称来实现。传递给 Web 服务的任何参数都可与一个处理返回数据的回调函数一起定义。
程序列表 13 中的示例是使用 JavaScript 代理调用一个名为GetCustomersByCountry()的 Web 方法。当终端用户点击页面上的一个按钮时,GetCustomersByCountry()函数即被调用。
程序列表13.用JavaScript代理调用Web服务
function GetCustomerByCountry() { var country = $get("txtCountry").value; InterfaceTraining.CustomersService.GetCustomersByCountry(country, OnWSRequestComplete); } function OnWSRequestComplete(results) { if (results != null) { CreateCustomersTable(results); GetMap(results); } }
本调用引用了服务中定义的InterfaceTraining命名控件、CustomersService类以及GetCustomersByCountry Web Method。它传递了一个从文本框获取的国家值,以及一个应在异步 Web 服务调用返回时调用的名为OnWSRequestComplete的回调函数。OnWSRequestComplete 处理从服务返回的Customer 对象数组,并将它们转换为一个表格显示在页面上。图1 显示的是调用生成的输出。
图1:通过向 Web 服务发起异步 AJAX 调用来绑定获取的数据
当某个 Web 方法应被调用但代理不应等待响应时,JavaScript 代理也可以向 Web 服务进行单向调用。例如,您可能想要调用一个Web 服务以开始一个进程(如工作流),但不想等待该服务的返回值。需要向服务发起单向调用时,可以直接省略程序列表13 中的回调函数。因为没有定义回调函数,代理对象将不会等待Web 服务返回数据。
补充:
Default.aspx
<html xmlns=""> <head runat="server"> <title>无标题页</title> <script type="text/javascript"> function HelloWorld() { var i = Service.HelloWorld(onSuccess); } function onSuccess(a) { window.alert(a); } </script> </head> <body> <form id="form1" runat="server" load="HelloWorld"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server"> <Services> <asp:ServiceReference Path="~/Service.asmx" /> </Services> </asp:ScriptManager> <input type="button" onclick="HelloWorld()" value="button"/> </div> </form> </body> </html>[WebService(Namespace = "")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。 [System.Web.Script.Services.ScriptService] public class Service : System.Web.Services.WebService { public Service () { //如果使用设计的组件,请取消注释以下行 //InitializeComponent(); } [WebMethod] public string HelloWorld() { return "Hello World"; }
对 Web 服务的异步调用可能会出现不同的错误,如网络中断、Web 服务不可用或返回异常等。幸运的是,ScriptManager 生成的 JavaScript 代理对象允许定义多个回调,以处理除上面列出的成功调用外的错误和失败。错误回调函数定义可以紧跟在对Web Method 的调用中的标准回调函数之后,如程序列表14 所示。
程序列表14.定义错误回调函数并显示错误
function GetCustomersByCountry() { var country = $get("txtCountry").value; InterfaceTraining.CustomersService.GetCustomersByCountry(country, OnWSRequestComplete, OnWSRequestFailed); } function OnWSRequestFailed(error) { alert("Stack Trace: " + error.get_stackTrace() + "/r/n" + "Error: " + error.get_message() + "/r/n" + "Status Code: " + error.get_statusCode() + "/r/n" + "Exception Type: " + error.get_exceptionType() + "/r/n" + "Timed Out: " + error.get_timedOut()); }