程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> JavaScript調用後台的三種方法實例(包含兩種Ajax),javascriptajax

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

編輯:關於.NET

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


方法一:直接使用<%=%>調用(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>[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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved