JavaScript調用后台的三種方法實例(包含兩種Ajax)


方法一:直接使用<%=%>調用(ASPX頁面)

前台JS,代碼如下:

<script type="text/javascript"> var methodStr = "<%=BehindMethod() %>"; alert(methodStr); </script>

后台方法,代碼如下:

public static string BehindMethod() { return "這是一個后台的方法"; }

說明:

1)BehindMethod()方法前的public訪問修飾符不要忘了;

2)此法有局限性——BehindMethod()只會在ASPX頁面加載或者回發的時候自動調用,不能人為控制調用。

方法二:用ajax調用

 前台JS/jQuery,代碼如下:

<script type="text/javascript"> var params = {ext:"p9hp"}; //參數,注意參數名要注意和后台方法參數名要一致 $(function(){ $("#btnOk").click(function(){ $.ajax({ type:"POST", //請求方式 url:"AjaxDemo.aspx/GetImg", //請求路徑:頁面/方法名字 data: params, //參數 dataType:"text", contentType:"application/json; charset=utf-8", beforeSend:function(XMLHttpRequest){ $("#tips").text("開始調用后頭方法獲取圖片路徑,請等待"); $("#imgFood").attr("src","image/loading.gif"); }, success:function(msg){ //成功 $("#imgFood").attr("src",eval("("+msg+")").d); $("#tips").text("調用方法結束"); }, error:function(obj, msg, e){ //異常 alert("OH,NO"); } }); }); }); </script>

頁面HTML,代碼如下:

<body>
    <form id="form1" runat="server"> <div> <label id="tips"></label> <img id="imgFood" /> <input value="點擊我,給你看一張圖片" type="button" width="35px" id="btnOk" /> </div> </form> </body>

ASPX后台方法,代碼如下:

[System.Web.Services.WebMethod]
public static string GetImg(string ext) { System.Threading.Thread.Sleep(5000);//為了有點等待的效果,延遲5秒 StringComparer sc = StringComparer.OrdinalIgnoreCase; string[] extArr = new string[] { "php", "asp", "aspx", "txt", "bmp" }; bool f = extArr.Any(s=>sc.Equals(s,ext)); //判斷傳入的后綴名是否存在 if (f) { return "image/54222860.jpg"; } return "image/star1.jpg"; }

說明:

1)后台方法前的[System.Web.Services.WebMethod]不能少;

2)還有一種形式的ajax,與上述很類似,不同之處在於:使用.ashx一般處理程序,將上述前台JS/jQuery代碼中url更改為請求的一般處理程序路徑/[地址欄參數](地址欄參數根據實際需要決定是否添加),如url:"AjaxDemo.ashx"。然后在AjaxDemo.ashx.cs的public void ProcessRequest(HttpContext context){...}中編寫相關代碼,最后以context.Response.Write("返回值")的形式返回返回值。

方法三:AjaxPro或者Ajax庫(也是ajax)

第一步:下載AjaxPro.dll(或者Ajax.dll),並且添加引用到項目

第二步:修改Web.config,在 <system.web> 節點下添加以下代碼。這里的Ajax.dll和Ajaxpro.dll引用方法是不一樣的,一定要注意。

<configuration> 
<system.web> 
<httpHandlers> <!-- Ajax.dll的配置文件寫法為,我下載到的是這個 --> <add verb="POST,GET" path="ajax/*.ashx" type="Ajax.PageHandlerFactory, Ajax" /> <!-- AjaxPro.dll的配置文件寫法為,根據你下載到的DLL文件選擇不同的配置語句--> <add verb="*" path="ajaxpro/*.ashx" type="AjaxPro.AjaxHandlerFactory, AjaxPro"/> </httpHandlers> </system.web> </configuration>

如果是IIS7,則需要在<system.webServer></system.webServer>里加上<add name="ajax"  verb="POST,GET" path="ajax/*.ashx" type="Ajax.PageHandlerFactory, Ajax" />

第三步:對AjaxPro用到的頁(如AjaxDemo.aspx)Page_Load事件中進行運行時注冊。如:

protected void Page_Load(object sender, EventArgs e) { Ajax.Utility.RegisterTypeForAjax(typeof(AjaxDemo));//是Ajax.dll的 AjaxPro.Utility.RegisterTypeForAjax(typeof(AjaxDemo));//Ajaxpro.dll的 }

對RegisterTypeForAjax方法的調用在頁面產生如下的javascript代碼(另外一種選擇,你也可以人工在頁面上添加如下的javascript代碼):


<script type="text/javascript" src="ajax/common.ashx"></script> <script type="text/javascript" src="ajax/NAMESPACE.CLASS,ASSEMBLYNAME.ashx"></script>

上面這段代碼的粗體部分NAMESPACE.PAGECLASS,ASSEMBLYNAME含義如下

NAMESPACE.CLASS

命名空間和類

ASSEMBLYNAME

程序集的名稱

Ajax也可以支持自定義類,但是需要這個類是可以被序列化的,即要在自定義類如User前加上[Serializable()]

[Serializable()]
public class User
{

 private int _userId; private string _firstName; private string _lastName; public int userId { get { return _userId; } } public string FirstName { get { return _firstName; } } public string LastName { get { return _lastName; } } public User(int _userId, string _firstName, string _lastName) { this._userId = _userId; this._firstName = _firstName; this._lastName = _lastName; } public User(){} [Ajax.AjaxMethod()]或者是[AjaxPro.AjaxMethod()] public User GetUser(int userId) { //Replace this with a DB hit or something :) return new User(userId,"Michael", "Schwarz"); } [Ajax.AjaxMethod()]或者是[AjaxPro.AjaxMethod()] public DataSet GetUserList(paramType1 param1, paramType2 param2, ...) { //Replace this with a DB hit or something :) return a DataSet; 
} [Ajax.AjaxMethod()]或者是[AjaxPro.AjaxMethod()] public DataTable GetUserList(paramType1 param1, paramType2 param2, ...) { //Replace this with a DB hit or something :) return a DataTable;
} }

那么,在調用頁面用RegisterTypeForAjax向服務器注冊代理類的代碼也要相應變更,代理類的名字不再是頁面類,而是我們自定義的類,代碼如下:

protected void Page_Load(object sender, EventArgs e) { Ajax.Utility.RegisterTypeForAjax(typeof(User));//是Ajax.dll的 AjaxPro.Utility.RegisterTypeForAjax(typeof(User));//Ajaxpro.dll的 }

第四步:編寫服務端方法,並且用[Ajax.AjaxMethod]標注

注意:

1)方法要寫成public,否則在JS里調用的時候會提示"不支持此屬性或方法";

2)在服務端函數,如果需要處理Session信息,此時必須在想支持Session的服務端函數的Ajax.AjaxMethod屬性上傳遞一個參數,如[Ajax.AjaxMethod(HttpSessionStateRequirement.Read)]。當然了,還可以是Write或ReadWrite,這個參數我們可以根據實際需求自行選擇。

在下面這個例子中,我們有一個文檔管理系統,當一個用戶對文檔進行編輯的時候會給這個文檔加鎖,其他用戶需要等到這個文檔可用時才能修改。不使用Ajax,用戶需要不斷等待刷新,因為不得不不斷的去檢查文檔的狀態是否為可用,這當然不是一個很好的方案。用ajax的sessionstate支持,這就比較容易了。

我們首先Document類中寫一個函數,這個函數通過遍歷文檔ID找到用戶需要的文檔,存儲到session里,並返回沒有占用的文檔:

[Ajax.AjaxMethod(HttpSessionStateRequirement.Read)]
public ArrayList DocumentReleased()
{

       if (HttpContext.Current.Session["DocumentsWaiting"] == null) { return null; } ArrayList readyDocuments = new ArrayList(); int[] documents = (int[])HttpContext.Current.Session["DocumentsWaiting"]; for (int i = 0; i < documents.Length; ++i) { Document document = Document.GetDocumentById(documents[i]); if (document != null && document.Status == DocumentStatus.Ready) { readyDocuments.Add(document); } } return readyDocuments; }

我們在屬性參數中指明了HttpSessionStateRequirement.Read,下面寫javascript函數來使用這個方法帶來的結果:

<script type="text/javascript">
function DocumentsReady_CallBack(response)
{
      if (response.error != null)
      {
             alert(response.error);
             return;
      }
      if (response.value != null && response.value.length > 0) { var div = document.getElementById("status"); div.innerHTML = "The following documents are ready!<br />"; for (var i = 0; i < response.value.length; ++i) { div.innerHTML += "<a href=\"edit.aspx?documentId=" + response.value[i].DocumentId + "\">" + response.value[i].Name + "</a><br />"; } } } </script> <body onload="setTimeout('Document.DocumentReleased(DocumentsReady_CallBack)', 10000);">

頁面加載后每10秒鍾向服務器函數請求一次。如果有返回,則callback函數檢查response,並把最新的結果顯示出來。

第五步:前台JS,調用User類的GetUser函數。Ajax封裝類會創建一個javascript函數,形式與服務端GetUser函數相似,帶一個參數,我們以"類名.函數名"的方式調用(如果是AjaxPor.dll,則以"命名空間.類名.函數名"的方式調用)。

作為Ajax最基本的功能,我們所需要做的只是調用這個方法並且傳遞參數,然后獲取返回值進行后續處理,代碼如下:

<script type="text/javascript">
    var response = User.GetUser(168);
    alert(response.value);
</script>

Ajax還有更強大的功能,這就是為什么所有的客戶端代理(如User.GetUser)同時帶有一個額外的定制屬性。這個屬性用來處理服務器響應的回調函數:

<script type="text/javascript">
function getUser(userId)
{
    User.GetUser(userId, GetUser_CallBack);
}

function GetUser_CallBack(response)
{
     if (response != null && response.value != null) { var user = response.value; if (typeof(user) == "object") { alert(user.FirstName + " " + user.LastName); } } } getUser(1); </script>

從上面的代碼中可以看出,我們為GetUser函數增加了一個額外參數GetUser_CallBack,這個參數就是用來處理服務器端響應的客戶端函數。這個CallBack函數接受一個帶有四個關鍵屬性的response對象:

value

服務器端函數執行的返回值(可能是一個字符串、自定義對象或者dataset)

error

如果發生錯誤,則返回錯誤信息.

request

原始的xmlHttpRequest請求

context

一個上下文對象

 

我們首先應該檢查是否有錯誤發生,你可以通過在服務器端函數拋出異常來實現這個error屬性。在上面這個例子中,我們簡單的alert了一個值,就是value屬性;request屬性可以用來取得額外的信息(更多的關於XmlHttpRequest的知識)。

說明:

返回值同服務器端對象一樣有三個屬性(FirstName, LastName and UserId)。

實例中我們在服務端函數返回了一個User類對象,那么Ajax還支持哪些返回類型呢?

Ajax可以支持除了我們上面GetUser函數返回的User類類型以外的很多類型。它可以直接支持integer, string, double, boolean, DateTime, DataSet 和 DataTable,也支持簡單的自定義類型和數組。其他的類型通過其ToString方式來返回字符串。

返回DataSet就像真正的.net Dataset。假設頁面中有個id為userinfo的table標簽,我們可以通過下面的方法在客戶端顯示:

<script type="text/javascript">
function getUserList(userId)
{
    User.GetUserList(param1, param2, ..., GetUserList_CallBack);
}

function GetUserList_CallBack(response)
{
     var ds = response.value;
     if (ds != null && typeof(ds) == "object" && ds.Tables != null) { $("#userinfo").empty(); var rowsLength = ds.Tables[0].Rows.length; if(rowsLength > 0) { for(var i = 0; i < rowsLength; i++) { var UserRow = ds.Tables[0].Rows[i]; $("#userinfo").append('<tr>'); $("#userinfo").append('<td style="width:60px;text-align:center;">' + UserRow.UserId + '</td>'); $("#userinfo").append('<td style="width:80px;text-align:left;">' + UserRow.FirstName + '</td>'); $("#userinfo").append('<td style="width:60px;text-align:left;">' + UserRow.LastName + '</td>'); $("#userinfo").append('</tr>'); } } else { $("#userinfo").append('<tr><td colspan="3" style="color:red;text-align:center">No data has been found!</td></tr>'); } } else { alert("Error:" + response.request.responseText); } } </script>

返回Unicode字符

Ajax.net可以從服務器端向客戶端返回Unicode字符,為了做到這一點,在服務端函數返回時返回的值必須是Html編碼的:

[Ajax.AjaxMethod()]
public string Test1(string name, string email, string comment) { string html = ""; html += "Hello " + name + "<br>"; html += "Thank you for your comment <b>"; html += System.Web.HttpUtility.HtmlEncode(comment); html += "</b>."; return html; }

代理的工作機制:

Ajax.PageHandlerFactory是通過反射來取得有定制屬性的函數的細節。Handler尋找帶有AjaxMethod定制屬性的函數,取得他們的特征(返回類型、名稱、參數)並依據這些信息創建客戶端代理。特別的,ajax創建一個與服務端函數類型相同的JavaScript對象作為代理。

Ajax技術可以給客戶端提供豐富的客戶體驗,而ajax.net為您容易的實現這樣強大的功能提供了可能,你可以通過下面的鏈接查看ajax.net的最新文檔:

Keep a close eye on the AJAX .Net wrapper website:http://ajax.schwarz-interactive.de/

For a good hands-on sample, check out the following demo application:http://ajax.schwarz-interactive.de/download/ajaxsample.zip

參考鏈接①:http://www.cnblogs.com/U2USoft/articles/332439.html

參考鏈接②:http://www.jb51.net/article/42176.htm


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM