我們在Web開發中經常會接觸到Ajax技術,同時Ajax技術也有很多種實現方式,那么,我們今天從第一種方式說起:ASP.NET原生控件實現Ajax。
ASP.NET原生控件用於Ajax技術的主要是UpdatePanel和ScriptManager,前者顧名思義,是一個可以用於盛放內容的容器,用於實現頁面的局部更新,在使用的時候直接將需要更新的內容放入即可。后者用於調用一些服務和腳本:例如我們本次Demo中使用JavaScript調用WebService服務。
本次Demo主要包含一個頁面,一個Web服務(WebService)和一個數據通用操作類(userHelper)來實現頁面無刷新檢測注冊時昵稱是否存在的功能。
首先,我們需要建立一個Web頁面(此處選用WebForm),大致代碼如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="WebApplication1.WebForm2" %>
<!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>注冊</title>
<script type="text/javascript">
function check() {
var Name = document.getElementById("txtName").value;
if (Name == "") {
alert("昵稱不能為空!");
}
else {
WebApplication1.WebService1.CheckName(Name, callbackCheck);
function callbackCheck(result) {
if (result == false) {
document.getElementById("checkFont").innerHTML = "<span>該昵稱已存在!請重新輸入!</span>";
}
else {
document.getElementById("checkFont").innerHTML = "<span>恭喜!該昵稱可以使用!</span>";
}
}
}
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager runat="server" ID="scriptManager">
<Services>
<asp:ServiceReference Path="~/WebService1.asmx" />
</Services>
</asp:ScriptManager>
<asp:UpdatePanel ID="Upnl" runat="server" UpdateMode="Always">
<ContentTemplate>
<div>
昵稱:<asp:TextBox ID="txtName" runat="server"></asp:TextBox><div id="checkFont">
</div>
</div>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnCheck" />
<asp:PostBackTrigger ControlID="btnReFresh" />
</Triggers>
</asp:UpdatePanel>
<asp:Button ID="btnCheck" runat="server" OnClientClick="check();" Text="檢測昵稱" />
<asp:Button ID="btnReFresh" runat="server" Text="刷新頁面" />
</form>
</body>
</html>
我在這個頁面中放入了一個ScriptManager,同時引用了一個WebService,然后將需要更新的部分放入了UpdatePanel。此外還有兩個Button,第一個用於檢測昵稱,第二個用於刷新頁面。大家看過代碼之后會發現我在UpdatePanel設置時加入了一個Triggers,那么這個是干什么的呢?獲取或設置觸發對 UpdatePanel 控件進行更新的回發控件事件。可以看到,我將檢測昵稱的Button設置為AsyncPostBackTrigger模式,此為點擊按鈕時不刷新整個頁面,只刷新UpdatePanel中的內容,而第二個按鈕設為PostBackTrigger模式,則會刷新整個頁面。
在第一個檢測昵稱的按鈕點擊時會調用一個js方法:check(),在check()函數中,我們首先去獲取TextBox中用戶輸入的名稱,然后將名稱傳入js調用的WebService方法中進行操作,得到結果后再根據結果去設置div要顯示的內容,如果存在則返回值為false。這里有一個js回調函數的概念:回調函數用於在異步操作中擴展第一個函數的功能,我們此處是為了在返回結果之后設置div的innerHTML的值。如果不使用回調函數而直接使用同步的話,可能會不執行函數的內容。
接下來是WebService,在建立WebService時,需要注意將[System.Web.Script.Services.ScriptService]這行代碼的注釋取消掉,VS2010中建立后會提示使用ASP.NET
Ajax從腳本中調用此Web服務時就需要這樣,否則會調用不到該方法。WebService中代碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Services; namespace WebApplication1 { /// <summary>
/// WebService1 的摘要說明 /// </summary>
[WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] // 若要允許使用 ASP.NET AJAX 從腳本中調用此 Web 服務,請取消對下行的注釋。
[System.Web.Script.Services.ScriptService] public class WebService1 : System.Web.Services.WebService { [WebMethod] public string HelloWorld() { return "Hello World"; } [WebMethod] public bool CheckName(string Name) { return userHelper.CheckName(Name); } } }
我們此處調用的CheckName方法,源自於數據通用類中的CheckName方法,userHelper中實現方法代碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data; using System.Data.SqlClient; namespace WebApplication1 { public class userHelper { public static bool CheckName(string Name) { string Con = @"Data Source=205ZHANGXK\SQLEXPRESS;Initial Catalog=MyQQ;Connect Timeout=30;Trusted_Connection=true"; using (SqlConnection sqlCon = new SqlConnection(Con)) { string Sql = "select count(*) from users where NickName='" + Name + "'"; sqlCon.Open(); SqlCommand cmd = sqlCon.CreateCommand(); cmd.CommandText = Sql; int res = int.Parse(cmd.ExecuteScalar().ToString()); if (res == 1) { return false; } else { return true; } } } } }
我在操作時連接了本地的數據庫MyQQ,該方法實現即為查找名稱,然后返回受影響的行數並返回結果。下面我們開始調試代碼:
我們可以看到數據庫中已經存在如下11條昵稱,在運行時我們輸入“豆豆”並點擊檢測昵稱按鈕,會發現代碼進入到WebSerivce中:
此時說明js腳本調用WebService方法已經成功,接下來會執行通用操作類中的方法:
和我們意料之中相同,“豆豆”這個昵稱已經在數據庫存在,接下來我們看看最終的結果:
在頁面上已經出現了我們預期的結果,我們再來試試輸入另外一個不存在的昵稱:
也已經達到了我們預期的效果。由於局部刷新的圖不太容易截到,這里就無法為大家呈現了。我們大家都知道服務器端Button在點擊時都會出現響應回發,因此點擊另外一個刷新頁面的按鈕,頁面會有明顯的閃爍(整個頁面全部刷新),這也體現了Ajax技術帶來的優勢,提升了用戶的體驗度。
我們通過一個簡單的Demo重現了ASP.NET 原生控件實現Ajax的功能,這也體現了ASP.NET本身封裝的強大之處,同時使用起來也很方便。但是由於ScriptManager和UpdatePanel控件本身為服務器端控件,在一定程度上會生成一些垃圾代碼,而且在請求時會生成整個頁面的控件樹,因此在批量使用的情況下會導致資源的占用率很高,這也是它本身的缺點。下次我會為大家帶來Ajax的另一種實現方式:JQuery自帶的ajax()方法結合ashx一般處理程序實現,這是一種輕量級的實現方式。