2013年5月21日 星期二

利用jQuery -Ajax 叫用 ASP.NET 的幾種方式

  jQuery 真是個佛心的發明,它讓前端叫用後端服務的方式更加靈活,使用 jQuery 之 ajax 呼中不同標的之差異:
呼叫  WebService :可用 JSON 或 Key:Value 傳送Form的欄位。
      如果用 return 回傳值,則dataType 要設成 "json"
      如果用 HttpContext.Current.Response.Write 回傳值,則 dataType 設成 "html" 或 "text"
呼叫 PageMethod:只能用 JSON 傳送 Form 欄位。
     只可用 return 回傳值,且dataType 要設成 "json",否則會收到字串形態的 JSON 物件
呼叫網頁(ASPX):只能用 key:value 傳送 Form 的欄位。
     只可用 HttpContext.Current.Response.Write 回傳值,則 dataType 設成 "html" 或 "text"

壹、配合 JSON 呼叫 WebService (ASMX)

處理結束之後,會用 return 返回處理結果,返的資料

$.ajax({
        url: 'user.asmx/checkLogin',
        type: 'POST',
        async: false,
        data: JSON.stringify({userId:'12345', password:'12345'}), 
        contentType:'application/json; charset=UTF-8',
        dataType:"json",      //如果要回傳值,請設成 json
        error: function(xhr) {//發生錯誤時之處理程序 },
        success: function(reqObj) {//成功完成時之處理程序 }
     }); 

底下是 user.asmx 的後端程式碼
using System;
using System.Web;
using System.Web.Services;
using System.Web.Security;
using System.Web.Services.Protocols;
using System.Collections.Generic;
using System.Web.Configuration;
using System.Text.RegularExpressions;

[WebService(Namespace = "http://SSO_Portal.moj.tw/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// 若要允許使用 ASP.NET AJAX 從指令碼呼叫此 Web 服務,請取消註解下一行。
[System.Web.Script.Services.ScriptService]
public class SSO_Service  : System.Web.Services.WebService 
{
    [WebMethod(EnableSession = true)]
    [System.Web.Script.Services.ScriptMethod]
    public string[] checkLogin(string userID, string password, string grCode) 
    {
        UserData user=new UserData();

        HttpContext.Current.Response.Redirect("Default.aspx");
        return null;
     }
}


貳、配合 JSON 呼叫 PageMethod

 處理結束之後,會用 return 返回處理結果,返的資料

$.ajax({
        url: 'checkLogin.aspx/chkUser',
        type: 'POST',
        async: false,
        data: JSON.stringify({userId:'12345', password:'12345'}), 
        contentType:'application/json; charset=UTF-8',
        dataType:"json",       //如果要回傳值,請設成 json
        error: function(xhr) {//發生錯誤時之處理程序 },
        success: function(reqObj) {//成功完成時之處理程序 }
     }); 

底下是 checkLogin.aspx 的 chkuser 後端程式碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Security;

namespace mySpace
{
    public partial class checkLogin : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }
 
        [WebMethod(EnableSession = true)]
        public static string chkUser(string userID, string grCode, string password)
        {
            string aaaa = "";
//          string uid=HttpContext.Current.Request.Form["userID"];  //收不到值
//          string pwd = HttpContext.Current.Request.Form["password"];
//          HttpContext.Current.Response.Redirect("Default.aspx"); //會出錯
            return null;
        }
     }
}


參、直接 POST 給另一個網頁(ASPX)

直接在處理的網頁內,用 Response 返回資料內容

$.ajax({
        url: 'checkLogin.aspx',
        type: 'POST',
        async: false,
        data: {userId:'12345', password:'12345'}, 
        contentType:'application/x-www-form-urlencoded; charset=UTF-8',
            //如果使用 "application/json; charset=utf-8" ,則後端程式無法
            //用 Request.Form["..."]  來取得傳送過來的資料
        dataType:"html",     //或用 "text"
            //如果不指定 dataType,會造成 jQuery 剖析時錯誤,所以會觸發 error
        error: function(xhr) {//發生錯誤時之處理程序 },
        success: function(reqObj) {//成功完成時之處理程序 }
     }); 

底下是 checkLogin.aspx 的後端程式碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Security;

namespace mySpace
{
    public partial class checkLogin : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
           String userid = this.Request.Form["userId"];
           String pwd = this.Request.Form["password"];
           this.Response.Write("Return Value");  //要返回的文字
           this.Response.Redirect("Default.aspx"); 
           //會把整個 Default.aspx 的html內容回傳,而不是執行轉向作業!
           Server.Transfer("default.aspx"); 
           //會把整個 Default.aspx 的html內容回傳,一樣不會執行轉向作業!
        }
     }
}


說明:

jQuery 的 contentType 對不同後端程式的影響

 application/x-www-form-urlencoded application/json
對WebService
  1. data: 不能序列化,否則會出錯
  2. 可由參數接收(用名字對應),接收參數不一定要等於傳送之個數
  3. 可由 HttpContext.Current.Request.Form 請值
  4. 可用HttpContext.Current.Response. Redirect("../Default.aspx"); 傳送網頁
  1. 只能透過參數接收傳過來的資料
  2. data: 一定要序列化,否則會出錯
  3. 不能使用 HttpContext.Current 物件(編譯時不會錯,執行時會錯!)
對ASPX網頁
  1. data: 不能序列化 JSON.stringify()
  2. 可由 this.Request.Form 請值
  3. 可用this.Response. Redirect("../Default.aspx"); 傳送網頁
  1. 可以呼叫網頁程式,但無法接收 Form 欄位資料
對 PageMethod不能使用這種方式呼叫 PageMethod,否則會變成是 Post 到 ASPX,反而執行 Page_Load,而忽略指定的 PageMethod


  1. 只能透過參數接收傳過來的資料
  2. data: 一定要序列化,否則會出錯
  3. 可以用 HttpContext.Current.Request.Form 但收不到值!
    4.不能使用 HttpContext.Current 物件(編譯時不會錯,執行時會錯!)
序列化:用JSON.stringify({})



jQuery.ajax() 的一般重要參數設定

accepts:??不清楚要設成什麼值??
async:true 是否採 非同步 呼叫,跨網域呼叫 及 dataType:"jsonp" 不支援 同步呼叫
beforeSend:function(jqXHR, settings){}  執行ajax之前先執行此callback程序,例如更改檔頭、 如果返回 false ,就會中止 ajax
cache:true | false
complete:function(jqXHR, textStatus){} 在 success 或 error 之後執行
  txtStatus 可能為 "success", "notmodified", "error", "timeout", "abort", or "parsererror"
contents: 指明針對後端回傳的資料, jQuery 要如何剖析? ????
contentType
    "application/x-www-form-urlencoded; charset=UTF-8"   用一般文字對傳送參數
    "application/json; charset=utf-8"                    用 json 物件傳送參數
converts: ????dataType-to-dataType converters
  {"* text": window.String, "text html": true, "text json": jQuery.parseJSON, "text xml": jQuery.parseXML}
crossDomain: false 是否允許跨網域 呼叫
data: {key:value, key:value} 要傳送的資料
dataFilter: function(String data, String dataType) 如何處理由後端回傳的原始資料
dataType:"xml", "json", "script", "html", "jsonp" 指明回傳資料的形態,預設是由 jQuery 自行判斷
scriptChartset: 只針對 dataType 設成 script 或 jsonp 是指定其內碼字集
error:function(jqXHR jqXHR, String textStatus, String errorThrown )
headers:{key:value, key:value} request 時,加入額外的表頭資訊
processData:true 預設 data: 選項的資料是會依照 contentType 進行轉換,如果不想轉換可將 processData 設為 false
success:function(PlainObject data, String textStatus, jqXHR jqXHR )
timeout:N 設定 timeout 的時間(毫秒)
type: "GET" 或 "POST" ("PUT", "DELETE" 也可使用但不一定有作用)

1 則留言:

  1. 謝謝分享,一直沒手工刻過ajax 及asp.net的呼叫,日後實作時再跟您請教。

    回覆刪除