4.2 PageMethods的用法
當ScriptManager的EnablePageMethods屬性值為True時,在繪制時ScriptManager會以Reflection巡覽此網頁類中是否有標示WebMethod Attribute的靜態函數,若有,會繪制一段Proxy的JavaScript程序代碼,這段程序代碼可以讓設計師在JavaScript中直接調用這個位于Server端的函數。
1. 建立一個新網頁,命名為UsePageMethods.aspx。
2. 放入ScriptManager控件。
3. 放入一個HTML的TextBox控件及一個HTML的Button控件,并鍵入程序4-5所示的JavaScript代碼。
4. 設定ScriptManager的EnablePageMethods屬性為True。
5. 在.cs中鍵入程序4-6的程序代碼。
程序4-5
Samples\4\AjaxDemo2\UsePageMethods.aspx <%@ Page Language="C#" AutoEventWireup="true" CodeFile= "UsePageMethods.aspx.cs" Inherits="UsePageMethods" %> <!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"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat= "server" EnablePageMethods="True"> </asp:ScriptManager> <script language=javascript> function helloMsg() { var ctl = $get('Text1'); PageMethods.GetHelloMessage(ctl.value,OnSucceeded,null); } function OnSucceeded(result, userContext, methodName) { if (methodName == "GetHelloMessage") { alert(result); } } </script> </div> <input id="Text1" type="text" /> <input id="Button1" type="button" value="button" onclick="helloMsg()"/> </form> </body> </html>
程序4-6
Samples\4\AjaxDemo2\UsePageMethods.aspx.cs using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class UsePageMethods : System.Web.UI.Page { [System.Web.Services.WebMethod] public static string GetHelloMessage(string str) { return "Hello " + str; } protected void Page_Load(object sender, EventArgs e) { } }
這個例子有兩個重點,當ScriptManager控件的EnablePageMethods屬性為True時,ScriptManager控件會為類中標示WebMethod Attribute的靜態函數建立Client端的JavaScript Proxy函數,之后于Client端的JavaScript程序代碼中便可以用PageMethods.<函數名稱>的方式來調用類中的函數。這里有個要注意的地方,ASP.NET AJAX中所有的動作都是異步的,調用PageMethods時也不例外,因此調用該函數時的參數格式中除了必須包含類函數所定義的參數外,同時要包含成功與失敗時所調用的JavaScript函數,如程序4-7所示。
程序4-7
Samples\4\AjaxDemo2\UsePageMethods.aspx <script language=javascript> function helloMsg() { var ctl = $get('Text1'); PageMethods.GetHelloMessage(ctl.value,OnSucceeded,OnFailed); } function OnSucceeded(result, userContext, methodName) { if (methodName == "GetHelloMessage") { alert(result); } } function OnFailed(error, userContext, methodName) { if(error !== null) { alert(error.get_message()); } } </script>
當調用PageMethods成功后,OnSucceeded函數就會被調用,這是調用GetHelloMessage時傳入的指定函數。在OnSucceeded函數中,result參數代表著調用類函數后的傳回值,userContext則是額外的參數,ASP.NET AJAX Client Framework一節中會提到這個參數的具體應用,methodName則是調用的函數名稱。會有methodName這個參數的原因是,如果每個PageMethods都建立一個專屬的成功函數,就顯得有些繁瑣,因此通常都只會有一個成功時的處理函數,運用methodName參數可以讓我們在成功時的處理函數中辨識調用的是哪一個函數,做出適當地處理。OnFailed函數會在失敗時被調用,error對象中包含著錯誤的信息,methodName則是調用的函數名稱。此程序的執行結果如圖4-2所示。

圖4-2
特別注意,PageMethods并不屬于Async-Postback機制,所以不受ScriptManager中的Async-Postback設置,如Timerout、ErrorMessage等屬性的影響,當失敗時,便必須在OnFailed函數中處理,如要設定timeout,可通過PageMethods.set_timeout函數來設定timeout時間,如下所示。
PageMethods.set_timeout(5000);
當調用處理時間超過timeout的設定時,Client端便會顯示超時信息。