ASP.NET 使用Ajax

轉載: http://www.cnblogs.com/dolphinX/p/3242408.htmljavascript

$.ajax向普通頁面發送get請求

這是最簡單的一種方式了,先簡單瞭解jQuery ajax的語法,最經常使用的調用方式是這樣:$.ajax({settings}); 有幾個經常使用的setting,所有參數及其解釋能夠去jQuery官方API文檔查詢css

1. type:請求方式 get/posthtml

2. url:請求的Uri前端

3. async:請求是否爲異步java

4. headers:自定義的header參數jquery

5. data:發往服務器的參數ajax

6. dataType:參數格式,常見的有string、json、xml等正則表達式

7. contents:決定怎樣解析response的一個」字符串/正則表達式」 mapjson

8. contentType:發送到服務器的額數據的內容編碼類型,它的默認值是"application/x-www-form-urlencoded; charset=UTF-8""。api

9. success:請求成功後調用的句柄

10.error:請求失敗後調用的句柄

沒使用過jQuery的ajax話這樣看有些雲裏霧裏的感受,來看一個簡單例子

首先使用Visual Studio新建一個WebApplication,把jQuery.js引入project,而後添加兩個頁面,Default.aspx做爲測試用

Default.aspx

複製代碼
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Web.Default" %>
<!DOCTYPE html >
<html>
<head runat="server">
    <title>Ajax</title>
    <script src="jQuery.js" type="text/javascript"></script>
    <style type="text/css">
        html, body, form
        {
            width: 100%;
            height: 100%;
            padding: 0px;
            margin: 0px;
        }
        
        #container
        {
            margin: 100px;
            height: 300px;
            width: 500px;
            background-color: #eee;
            border: dached 1px #0e0;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <div id="container">
        <input type="button" value="Test Ajax" onclick="testGet()" />
        <br />
    </div>
    <script type="text/javascript">
        function setContainer(text) {
            document.getElementById("container").innerHTML += ('<br/>' + text);
        }

        function testGet() {
            $.ajax({
                type: 'get',
                url: 'NormalPage.aspx',
                async: true,
                success: function (result) {
                    alert(result);
                },
                error: function () {
                    setContainer('ERROR!');
                }
            });
        }
    </script>
    </form>
</body>
</html>
複製代碼

NormalPage.aspx做爲請求頁面,先不作任何處理。在Default.aspx頁面中的JavaScript中能夠看到testGet函數就利用jQuery的ajax向Normal.aspx發送了了一個get請求,沒寫的參數使用jQuery默認參數,這個調用沒使用任何參數,簡單向Normal.aspx頁面發送請求,請求成功則alert所有response(即success方法參數:result,jQuery會把responseText傳入success方法第一個參數),請求失敗則向DIV中添加一行錯誤提示文本。若是一切正常,能夠看到頁面彈出對話框,對話框內內容便是Normal.aspx頁面內容

image

一個簡單的get請求完成了,這樣的結果通常沒有多大用處,也不是ajax意圖所在,使用Ajax主要是想使用JavaScript能夠異步向服務器發送特定請求,獲取服務器相關數據,好比向服務器詢問天氣,而後得到天氣數據,更新頁面,而不是獲取整個頁面,換句話說,使用Ajax自己就是爲了擺脫更新整個頁面來更新頁面數據這種模式,僅僅須要服務器給咱們數據便可,這就須要調用服務器端的特定方法。

$.ajax GET請求調用服務器特定方法

咱們這時候須要修改NormalPage.aspx,爲其添加幾個方法供Default.aspx測試調用

複製代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Web
{
    public partial class NormalPage : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string action = Request.QueryString["action"];
            Response.Clear(); //清除全部以前生成的Response內容
            if (!string.IsNullOrEmpty(action))
            {
                switch (action)
                {
                    case "getTime":
                        Response.Write(GetTime());
                        break;
                    case "getDate":
                        Response.Write(GetDate());
                        break;
                }
            }
            Response.End(); //中止Response後續寫入動做,保證Response內只有咱們寫入內容
        }


        private string GetDate()
        {
            return DateTime.Now.ToShortDateString();
        }

        private string GetTime() 
        {
            return DateTime.Now.ToShortTimeString();
        }
    }
}
複製代碼

而後爲Default.aspx添加一個新的方法,並修改button的onclick方法爲新寫的函數

複製代碼
function testGet2() {
            $.ajax({
                type: 'get',
                url: 'NormalPage.aspx',
                async: true,
                data:{action:'getTime'},
                success: function (result) {
                    setContainer(result);
                },
                error: function () {
                    setContainer('ERROR!');
                }
            });
        }
複製代碼

testGet2函數是在testGet函數的基礎上作了些許修改,首先對success方法作了更改,把獲得的response寫到頁面;而後對請求添加了data參數,請求向服務器發送了一個action:getTime的鍵值對,在get請求中jQuery會把此參數轉爲url的參數,上面寫法和這種寫法效果同樣

複製代碼
function testGet3() {
            $.ajax({
                type: 'get',
                url: 'NormalPage.aspx?action=getTime',
                async: true,
                success: function (result) {
                    setContainer(result);
                },
                error: function () {
                    setContainer('ERROR!');
                }
            });
        }
複製代碼

看一下執行效果,這是Chrome的監視結果

image

若是調試咱們發現這個請求調用的服務器頁面NormalPage.aspx的GETime方法,而且response中只包含對有用的數據,若是把請求中參數的值改成getDate,那麼就會調用對應GetDate方法。

$.ajax POST與json

這樣向一個頁面發送請求而後在Load事件處理程序中根據參數調用不一樣方法,清除Response,寫入Response,終止Response,並且傳入的參數侷限性太大,好業餘的趕腳,看看專業些解決方法。爲project添加一個General Handler類型文件,關於HttpHandler相關內容本文不作詳細解釋,只需知道它能夠很是輕量級的處理HTTP請求,不用走繁瑣的頁面生命週期處理各類非必需數據。

Handler.ashx.cs

複製代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Newtonsoft.Json;

namespace Web
{
    /// <summary>
    /// Summary description for Handler
    /// </summary>
    public class Handler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            Student stu = new Student();
            int Id = Convert.ToInt32(context.Request.Form["ID"]);
            if (Id == 1)
            {
                stu.Name = "Byron";
            }
            else
            {
                stu.Name = "Frank";
            }
           string stuJsonString= JsonConvert.SerializeObject(stu);
           context.Response.Write(stuJsonString);
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}
複製代碼

關於這個類語法本文不作詳細說明,每次發起HTTP請求ProcessRequest方法都會被調用到,Post類型請求參數和一再Request對象的Form中取得,每次根據參數ID值返回對應json對象字符串,爲了展現json格式數據交互,須要爲項目引入json.net這一開源類庫處理對象序列化反序列化問題,而後建立一個Student類文件

Student.cs

複製代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Web
{
    public class Student
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }
}
複製代碼

看看頁面如何處理

複製代碼
function testPost() {
            $.ajax({
                type: 'post',
                url: 'Handler.ashx',
                async: true,
                data: { ID: '1' },
                success: function (result) {
                    setContainer(result);
                    var stu =eval ('('+result+')');
                    setContainer(stu.ID);
                    setContainer(stu.Name);
                },
                error: function () {
                    setContainer('ERROR!');
                }
            });
        }
複製代碼

結果是這個樣子的

image

上面代碼向Handler.ashx發送一Post請求,比且帶有參數{ID:’1’},能夠看到結果,若是用調試工具能夠發現,獲得的result是一個json格式的字符串,也就是往Response寫的對象序列化後的結果。這樣就實現了比較專業些的方式調用Ajax,可是有一個問題依舊存在,HttpHandler會自動調用ProcessRequest方法,可是也只能調用該方法,若是想調用不一樣方法只能像普通頁面那樣傳遞一個參數代表調用哪一個方法,或者寫不一樣的Handler文件。

WebService與ScriptManager

微軟向來很貼心,看看微軟怎麼處理上面的困惑,那就是利用WebService,WebService配合SCriptManager有客戶端調用的能力,在項目中添加一個Webservice文件

WebService.asmx

複製代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;

namespace Web
{
    /// <summary>
    /// Summary description for WebService
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    [System.Web.Script.Services.ScriptService]
    public class WebService : System.Web.Services.WebService
    {

        [WebMethod]
        public Student GetStudent(int  ID)
        {
            if (ID == 1)
            {
                return new Student() { ID = 1, Name = "Byron" };
            }
            else
            {
                return new Student() { ID = 2, Name = "Frank" };
            }
        }

        

        [WebMethod] 
        public string GetDateTime(bool isLong) 
        { 
            if (isLong) 
            { 
                return DateTime.Now.ToLongDateString(); 
            } 
            else 
            { 
                return DateTime.Now.ToShortDateString(); 
            } 
        }

    }
}
複製代碼

代碼中加黃的code默認是被註釋掉的,要想讓客戶端調用須要把註釋去掉,Service中定義了兩個方法,寫個測試方法讓客戶端調用第一個方法根據參數返回對應對象,首先須要在頁面from內加上ScriptManager,引用剛纔寫的WebService文件

Default.aspx

複製代碼
<form id="form1" runat="server">
    <asp:ScriptManager ID="clientService" runat="server">
        <Services>
            <asp:ServiceReference Path="~/WebService.asmx" />
        </Services>
    </asp:ScriptManager>
    <div id="container">
        <input type="button" value="Test Ajax" onclick="testPost2()" />
        <br />
    </div>
...
複製代碼

而後添加JavaScript測試代碼

複製代碼
function testPost2() {
            Web.WebService.GetStudent(1, function (result) {
                setContainer(result.ID);
                setContainer(result.Name);
            }, function () {
                setContainer('ERROR!');
            });
        }
複製代碼

測試代碼中須要顯示書寫WebService定義方法完整路徑,WebService命名空間.WebService類名.方法名,而出入的參數列表前幾個是調用方法的參數列表,由於GetStudent只有一個參數,因此只寫一個,若是有兩個參數就順序寫兩個,另外兩個參數能夠很明顯看出來是響應成功/失敗處理程序。看看執行結果:

image

觀察仔細會發現使用ScriptManager和WebService組合有福利,在WebService中傳回Student對象的時候並無序列化成字符串,而是直接返回,看上面圖發現對象已經自動轉換爲一json對象,result結果能夠直接操做,果然很是貼心。而上一個例子中咱們獲得的response是一個json字符串,在客戶端須要用eval使其轉換爲json對象。

ScriptManager+WebSefvice調用ajax帶來了很大的便利性,但同時犧牲了不少靈活性,咱們無法像jQuery那樣指定不少設置有沒有一箭雙鵰的辦法呢

$.ajax+WebService

jQuery調用Handler幾乎完美了,可是不能處理多個方法,上面例子咱們能夠發現WebService能夠實現這一功能,那麼能不能jQUery調用WebService的不一樣方法呢?答案是確定的,試一試用jQuery調用剛纔WebService定義的第二個方法。寫一個測試函數

複製代碼
function testPost3() {
            $.ajax({
                type: 'post',
                url: 'WebService.asmx/GetDateTime',
                async: true,
                data: { isLong: true },
                success: function (result) {
                    setContainer($(result).find('string').text());
                },
                error: function () {
                    setContainer('ERROR!');
                }
            });
        }
複製代碼

調用方式沒有多大變化,簡單依舊,只要把URL改成WebService路徑+須要調用的方法名,而後把參數放到data裏就能夠了。咱們看看結果:

image

經過上圖能夠看到,jQuery調用WebService默認會返回一個XML文檔,而須要的數據在 <string>節點中,只須要使用jQuery解析xml的語法就能夠輕鬆獲得數據。若是但願返回一個json對象怎麼辦?那就得和調用Handler同樣使用json.net序列化,而後前端使用eval轉換了,也不會過於複雜。我在項目中最常使用這個模式,這樣既保持了jQuery的靈活性又能夠在一個Service中書寫多個方法供調用,還不用走複雜的頁面生命週期

json.net和本文示例源代碼

json.net是一個開源的.net平臺處理json的庫,能夠序列化Dictionay嵌套等複雜對象,關於其簡單使用有時間會總結一下,能夠自codeplex上獲得其源碼和官方說明。本文的源代碼能夠點擊這裏得到。

相關文章
相關標籤/搜索