Tìm kiếm Blog này

Sử Dụng Ajax Trong ASP.Net - Làm quen với Ajax qua ví dụ

(Nguồn từ http://zensoft.vn)
Một trong những kỹ thật lập trình đình đám nhất hiện nay mà chúng ta không thể không nghiên cứu. Qua các bài viết này tôi hi vọng sẽ giúp các bạn hiểu được cũng lắm vững các nguyên tắc lập trình cơ bản nhất của Ajax trong môi trường .Net.
AJAX là gì?
AJAX, viết tắt từ Asynchronous JavaScript and XML (JavaScript và XML không đồng bộ), là bộ công cụ cho phép tăng tốc độ ứng dụng web bằng cách cắt nhỏ dữ liệu và chỉ hiển thị những gì cần thiết, thay vì tải đi tải lại toàn bộ trang web. AJAX không phải một công nghệ đơn lẻ mà là sự kết hợp một nhóm công nghệ với nhau. Trong đó, HTML và CSS đóng vai hiển thị dữ liệu, mô hình DOM trình bày thông tin động, đối tượng XMLHttpRequest trao đổi dữ liệu không đồng bộ với máy chủ web, còn XML là định dạng chủ yếu cho dữ liệu truyền dữ liệu và Javacript có nhiệm vụ lắp ráp chúng lại với nhau.
Các bạn có thể tìm hiểu kĩ hơn về Ajax qua bài viết Kỹ thuật lập trình Ajax
Hiển nhiên để phát triển ứng theo phong các AJAX chúng ta cần phải biết về JavaScript, DOM, CSS, HTML, XML… Điều đó thật không dễ dàng gì. Thật may là hiện tại đã có khá nhiều thư viện cho phép chúng ta phát triển ứng dụng AJAX nhanh và đơn giản hơn nhiều. (Chúng ta sẽ tìm hiểu về những thư viện này trong các bài sau ;-) ).
Ví dụ
Trong ví dụ tôi sẽ trình bày sau đây sẽ giúp chúng ta làm quen với cách mà AJAX làm việc, tất nhiên tại ví dụ này chúng ta sẽ không dùng những thư viện xây dựng sẵn.
AjaxEx1.aspx


Code:

Thí dụ về Ajax

Hãy chọn nhóm thư mục
Chọn thư mục:
Chọn bài viết:
AjaxEx1.aspx.cs protected void Page_Load(object sender, EventArgs e) {
ddlSuperCategories.DataSource = SuperCategoriesBF.GetSuperCategoriesAll(); ddlSuperCategories.DataTextField = "Title"; ddlSuperCategories.DataValueField = "SuperCategoryID"; ddlSuperCategories.DataBind(); ddlSuperCategories.Items.Insert(0, new ListItem("Chọn nhóm thư mục...", "0")); // handle change events on client ddlSuperCategories.Attributes.Add("onchange", "getCategories(this.value);"); ddlCategories.Attributes.Add("onchange", "getArticles(this.value);"); ddlArticles.Attributes.Add("onchange", "displayResults();");
} AjaxServer.aspx.cs protected void Page_Load(object sender, EventArgs e) { int superCategoryID=0; if (Request["superCategoryID"] != null) int.TryParse(Request["superCategoryID"], out superCategoryID); int categoryID = 0; if (Request["categoryID"] != null) int.TryParse(Request["categoryID"], out categoryID); // either retrieve cities or class dates if (categoryID != 0) GetArticles(categoryID); else GetCategories(superCategoryID); } /// /// Trả về dữ liệu thư mục bài viết theo chuẩn XML /// /// private void GetCategories(int superCategoryID) { // lấy dữ liệu List categories = CategoriesBF.GetCategoriesBySuperCategoryID(superCategoryID); StringBuilder sb = new StringBuilder(); sb.Append(@""); sb.Append(@""); sb.Append(@"Chọn thư mục..."); foreach (CategoriesBF c in categories) { sb.Append(@""); } sb.Append(@""); Response.Clear(); Response.ContentType = "text/xml"; Response.Write(sb.ToString()); Response.End(); } private void GetArticles(int categoryID) { // lấy dữ liệu List articles = ArticlesBF.GetArticlesPublishedPagedByCategoyID(categoryID, 0, 10); //các bạn có thể hiểu là lấy 10 bài viết đầu tiên trong thư mục có ID = categoryID StringBuilder sb = new StringBuilder(); sb.Append(@""); sb.Append(@""); sb.Append(@"
Chọn bài viết...
"); // note: class is a keyword, therefore prefix with '@' foreach (ArticlesBF a in articles) { sb.Append(@"
"); } sb.Append(@"
"); Response.Clear(); Response.ContentType = "text/xml"; Response.Write(sb.ToString()); Response.End(); }


Click vào đây để xem ví dụ

Hướng dẫn tạo website với Dynamic Theme.

Mình sẽ hướng dẫn từng bước một và chi tiết để các bạn có thể hiểu rõ và làm được.
Trước hết, chúng ta tạo một website mới với công cụ Visual Studio 2005. Đây là giao diện của ứng dụng:

Giao Diện Black
Giao Diện White
Bước thứ 1:
Tạo một thư mục và đặt tên là App_Code. Trong thư mục này ta tạo một Class có tên là Theme.cs
Nội Dung trang đó như sau:
public class Theme
{
private string _name;

// Lấy Tên.
public string Name
{
set
{
_name = value;
}
get
{
return _name;
}
}

// Contractor
public Theme(string name)
{
Name = name;

}
}
Bước 2: Tạo thư mục App_Themes để quản lý các Theme sẽ sử dụng trong ứng dụng của mình. Ở đây, mình tạo 2 Theme có tên là Black và White. Tiếp Theo, ta tạo tiếp một Class mới trong thư mục App_Code có tên là ThemeManager.cs. Class này có nhiệm vụ tìm kiếm và quản lý các Theme có trong thư mục App_Theme. Nó sẽ liệt kê tất cả các Theme tồn tại trong thư mục App_Themes.
public class ThemeManager
{

public static List GetThemes()
{
DirectoryInfo dInfo = new DirectoryInfo(System.Web.HttpContext.Current.Serve r.MapPath("App_Themes"));
DirectoryInfo[] dArrInfo = dInfo.GetDirectories();
List list = new List();

foreach (DirectoryInfo d in dArrInfo)
{
Theme temp = new Theme(d.Name);
list.Add(temp);
}

return list;
}

}
Bước 3:
Tạo một trang Master để sử dụng chung cho tất cả các trang khác trong ứng dụng, đặt tên là Default.Master. trong trang này, chúng ta tạo ra 1 ObjectDataSource, có tên là ThemeDataSource để lấy danh sách các Theme có trong thư mục App_Themes:
Để thay đổi Theme, chúng ta có thể sử dụng DropDownList hoặc RadioButton List. Ở đây mình sử dụng RadioButton List.
Các bạn hãy để ý nhé, với RadionButton List, chúng ta nhớ phải đặt thuộc tính DataSourceID = "ThemeDataSource" để lấy các danh sách Theme. Chúng ta viết 2 sự kiện cho thẻ này:
protected void choiceTheme_DataBound(object sender, EventArgs e)
{
choiceTheme.SelectedValue = Page.Theme;
}
protected void choiceTheme_SelectedIndexChanged(object sender, EventArgs e)
{
Session.Add("MyTheme",choiceTheme.SelectedValue);
Server.Transfer(Request.FilePath);
}
Bước Tiếp Theo: Chúng ta tạo một Class có tên là BasePage.cs để xác định Theme mặc định chúng ta sẽ sử dụng. ở đây, mặc định sẽ là Theme White:
public class BasePage: System.Web.UI.Page
{

protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
if (Session["MyTheme"] == null)
{
Session.Add("MyTheme", "White");
Page.Theme = (string)Session["MyTheme"];
}
else
{
Page.Theme = (string)Session["MyTheme"];
}
}
}
Bước cuối cùng, những trang bạn muốn sử dụng Dynamic Themes chỉ cần kế thừa Lớp basePage là được.
public partial class _Default : BasePage
{
protected void Page_Load(object sender, EventArgs e)
{

}
}
Ứng dụng Dynamic Theme đã hoàn thành. Bạn có thể tùy biến giao diện cho riêng mình với việc thay đổi Stylesheet riêng với BlackStyle.css và WhiteStyle.css. Bạn có thể download mã nguồn của ứng dụng này tại đây.
Theo zensopft.vn

Sử dụng Ajax trong lập trình ASP.NET

Ajax ngày càng được sử dụng rộng rãi, nó giúp xoá mờ khoảng cách giữa máy tính (desktop) và Internet. Tác giả Phạm Công Định đã có bài giới thiệu tổng quát về kỹ thuật lập trình web sử dụng Ajax, tiếp tục chủ đề này, trong bài viết này tôi giới thiệu một công cụ phát triển ứng dụng kiểu Ajax với ASP.NET.

Ajax.NET

Ajax.NET là thư viện Ajax cho .NET được phát triển bởi tác giả người Đức tên là Michael Schwarz ( \n info@schwarz-interactive.deĐịa chỉ thư điện tử này đang được bảo vệ khỏi chương trình thư rác, bạn cần bật Javascript để xem nó Địa chỉ thư điện tử này đang được bảo vệ khỏi chương trình thư rác, bạn cần bật Javascript để xem nó ), mục đích nhằm giúp lập trình viên .NET dễ dàng khai thác sức mạnh của Ajax trong các ứng dụng web của mình. Thư viện này được cung cấp miễn phí trên Internet, bạn có thể yêu cầu tác giả cho tải về cả mã nguồn nếu muốn. Thư viện Ajax.NET hiện cũng được phát triển dưới một dự án nguồn mở tên là BorgWorX Ajax.NET (http://www.borgworx.net/) với nhiều chức năng mở rộng. Ở đây tôi chỉ đề cập tới phiên bản Ajax.NET đầu, sau khi làm quen với thư viện này bạn có thể dễ dàng khám phá phiên bản mở rộng trong dự án nguồn mở trên, thậm chí tham gia dự án này.



Ajax.NET giúp lập trình viên sử dụng Ajax mà không phải bận tâm đến mã lệnh tương tác trực tiếp với các đối tượng XMLHttpRequest, xử lý dữ liệu XML, DOM. Bằng cách sử dụng những khả năng của môi trường lập trình .NET như HttpHandler, reflection, attributes... nó tự động sinh ra những mã lệnh cần thiết giúp việc tương tác giữa client/server hoàn toàn "trong suốt" cũng như đơn giản hoá việc gọi hàm, xử lý những dữ liệu phức tạp như mảng, bảng, đối tượng trên phía client.

Để hiểu rõ về cách hoạt động cũng như sử dụng Ajax.NET trong một ứng dụng ASP.NET, tôi trình bày từng bước thực hiện một ứng dụng minh hoạ đơn giản. Ứng dụng là một form đăng ký thành viên như chúng ta thường gặp trên các diễn đàn, hoặc đăng ký tài khoản e-mail... Nguyên tắc hoạt động của form là mỗi khi có thành viên mới đăng ký sẽ sử dụng Ajax để kiểm tra xem tên (username) đã có chưa và hiển thị danh sách các thành phố dựa trên quốc gia mà thành viên sinh sống. Các thay đổi sẽ thực hiện ở "hậu trường" mà không phải thực hiện nạp lại toàn bộ trang web hay lưu tạm một lượng lớn dữ liệu ở client như cách thông thường.

Bạn có thể tham khảo ứng dụng minh hoạ của bài viết này tại http://www.mobicolors.com/Tiendq/AjaxDemo/, file zip chứa toàn bộ mã nguồn của ứng dụng cũng có thể tải về từ địa chỉ trên. Ứng dụng này được xây dựng với Visual Studio 2005 phiên bản CTP 09/2005, sử dụng ngôn ngữ C#, tuy nhiên các kỹ thuật trình bày ở đây sẽ không có gì khác biệt khi sử dụng với VB.NET hoặc Visual Studio .NET 2003.

Cài đặt ban đầu

Trước tiên cần tạo một website mới trong VS2005, sau đó bạn tạo một tham chiếu (reference) tới thư viện Ajax.NET (file AjaxPro.dll nếu sử dụng với VS.NET 2003, hoặc file AjaxPro.2.dll nếu là VS2005). Thư viện Ajax.NET Professional sử dụng trong bài viết này là phiên bản mới nhất 5.11.4.2, có thể tải về từ http://www.schwarz-interactive.de.

Tiếp theo, cài đặt HttpHandler của Ajax.NET vào website vừa tạo bằng cách thêm các dòng sau đây vào file Web.config (nếu sử dụng VS2005 bạn phải tự thêm file này vào website).






type="AjaxPro.AjaxHandlerFactory, AjaxPro.2"/>


...


Các bước trên chỉ cần thực hiện một lần với một website, sau đó chúng ta chuyển sang phần khai báo và viết các hàm xử lý trên phía server.

Xây dựng các hàm Ajax phía server

Nhìn chung việc xây dựng các hàm để xử lý những yêu cầu từ phía client không có gì khác so với các các quy định của .NET, ngoại trừ một việc là những hàm này sẽ được "đánh dấu" bằng một thuộc tính tên là AjaxMethodAttribute và có một số hạn chế sẽ được trình bày ở phần sau. Dưới đây là khai báo của hàm CheckAvailablity sử dụng trong ứng dụng để kiểm tra xem một username đã được đăng ký chưa. Để tập trung vào chủ đề chính, tôi chỉ đơn giản lưu username vào một biến session, như vậy là trong cùng một session sẽ không đăng ký được hai thành viên có username giống nhau.

[AjaxPro.AjaxMethod]

public bool CheckAvailablity(string userName)
{
return (null == Session[userName]);
}

Hàm CheckAvailability hoàn toàn có thể được sử dụng lại trong các hàm khác ở phía server mà không phải thay đổi gì cả, ví dụ hàm này được dùng để kiểm tra username khi người sử dụng nhấn vào nút Sign Up, phát sinh sự kiện postback gửi dữ liệu về xử lý trên server:

protected void btnSignUp_Click(object sender, EventArgs e)
{
if (CheckAvailablity(txtUserName.Text))
{
// register new user...
}
// ...
}

Cũng tương tự cách khai báo như trên, chúng ta có hàm GetStateList dùng để trả về danh sách các thành phố của quốc gia tương ứng mỗi khi người sử dụng thay đổi tên quốc gia ở phía client. Hàm này trả về một đối tượng kiểu DataTable, tuy nhiên với sự hỗ trợ của Ajax.NET sẽ không có khó khăn gì để xử lý và hiển thị dữ liệu này trên form ở phía client.

[AjaxPro.AjaxMethod]

public DataTable GetStateList(int countryIndex)
{
DataTable dt = new DataTable();
dt.Columns.Add("StateCode", typeof(string));
dt.Columns.Add("StateName", typeof(string));
// populate state list
return dt;
}

Cuối cùng, để các hàm trên có thể được gọi từ phía client thì chúng ta cần phải đăng ký với Ajax.NET. Sau khi đăng ký với Ajax.NET, thường thực hiện trong hàm xử lý sự kiện Page_Load của trang web, Ajax.NET sẽ tự động sinh ra các mã lệnh JavaScript cần thiết của các hàm này ở phía client. Khi các hàm ở client được gọi thực hiện, dữ liệu sẽ chuyển tới các hàm tương ứng trên server để xử lý và trả về kết quả sau đó.

public partial class Tiendq_AjaxDemo : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
AjaxPro.Utility.RegisterTypeForAjax(typeof(Tiendq_ AjaxDemo));
if (false == IsPostBack)
{
// ...
}
}
// ...
}

Sử dụng hàm Ajax ở client

Sau khi xây dựng xong các hàm Ajax phía server, chúng ta có thể sử dụng các hàm này ở client (mã lệnh viết bằng JavaScript) với cú pháp như đã khai báo ở phía server (mã lệnh viết bằng C#), việc gọi hàm có thể thực hiện đồng bộ (synchronous) hoặc bất đồng bộ (asynchronous). Khi gọi hàm theo kiểu synchronous sẽ nhận được dữ liệu trả về tức thời (hoặc phải chờ tuỳ theo tốc độ của kết nối tới server), khi gọi hàm theo kiểu bất đồng bộ (asynchronous) thì dữ liệu sẽ được trả về qua một hàm callback, đoạn mã lệnh thực hiện gọi hàm trong trường hợp này sẽ tiếp tục thực hiện và không cần chờ dữ liệu trả về từ phía server. Hàm callback sẽ được gọi khi có dữ liệu từ server trả về sau đó.

Gọi hàm theo kiểu đồng bộ:

function OnCheckAvailablity(userName)
{
var res = Tiendq_AjaxDemo.CheckAvailablity(userName);
alert(res.value);
}

Gọi hàm theo kiểu bất đồng bộ:

function OnCheckAvailablity(userName)
{
Tiendq_AjaxDemo.CheckAvailablity(userName,
OnCheckAvailablity_Callback);
}

function OnCheckAvailablity_Callback(res)
{
if (null != res.error)
{
alert("Error message goes here!");
return;
}

if (res.value)
{
// process data
}

else
{
// raise error
}
}

Trong cả hai trường hợp gọi hàm trên, dữ liệu trả về là một đối tượng có cấu trúc như sau:


Tên trường

Mô tả

Value

Dữ liệu trả về khi gọi thực hiện hàm phía server, kiểu dữ liệu thực sự phụ thuộc vào khai báo hàm phía server (có thể là chuỗi ký tự, số nguyên, mảng,...).

Error

Thông báo lỗi nếu có.

Request

Dữ liệu trả về của đối tượng XMLHttpRequest, trường hợp muốn lấy thêm các thông tin trả về khác. Xem tài liệu về đối tượng XMLHttpRequest để biết chi tiết.

Context

Tham chiếu tới đối tượng phía client.

Sau đây sẽ là phần mã lệnh gọi thực hiện các hàm CheckAvailablity và GetStateList ở phía client mà chúng ta đã khai báo ở phần trên. Hàm CheckAvailablity sẽ được gọi thực hiện khi người sử dụng nhấn vào nút Check để kiểm tra username muốn đăng ký đã tồn tại chưa, hàm GetStateList được gọi mỗi khi người sử dụng chọn quốc gia khác nhau để cập nhật lại danh sách thành phố của quốc gia đó:

function OnCheckAvailablity(userName)
{
if (userName.length > 0)
Tiendq_AjaxDemo.CheckAvailablity(userName,
OnCheckAvailablity_Callback);
else
alert("User name is required field.");
}

function OnCheckAvailablity_Callback(res)
{
if (null != res.error)
{
alert("Error message goes here!");
return;
}

if (res.value)
{
document.all("lblCheckStatus").innerHTML = "" + document.forms[0].txtUserName.value + " is available."
document.all("lblCheckStatus").className = "cssAvailable";
}
else
{
document.all("lblCheckStatus").innerHTML = "" + document.forms[0].txtUserName.value + " is not available."
document.all("lblCheckStatus").className = "cssNotAvailable";
}
}

function OnSelectCountry(countryIndex)
{
if (countryIndex > 0)
Tiendq_AjaxDemo.GetStateList(countryIndex, GetStateList_Callback);
else
{
ResetStateList();
document.forms[0].cboStates.disabled = true;
}
}

function GetStateList_Callback(res)
{
if (null != res.error)
{
alert("Error message goes here!");
return;
}

var dt = res.value;

if ((null != dt) && ("object" == typeof(dt)))
{
document.forms[0].cboStates.disabled = false;
ResetStateList();

var oItem = null;

for (var i = 0; i < dt.Rows.length; ++ i)
{
oItem = document.createElement("OPTION");
oItem.text = dt.Rows[i].StateName;
oItem.value = dt.Rows[i].StateCode;
document.forms[0].cboStates.add(oItem);
}
}
}

Nhờ có Ajax.NET, ở đoạn mã lệnh JavaScript trên kiểu dữ liệu phức tạp DataTable trả về từ hàm GetStateList có thể xử lý dễ dàng theo cách quen thuộc như dùng ngôn ngữ của .NET (C#, VB.NET). Hoàn toàn không cần thao tác với XML, hay DOM.

Một số chú ý

Ở ứng dụng này tôi mới chỉ minh hoạ trường hợp gọi hàm được khai báo trong cùng một lớp của trang web, trường hợp khai báo hàm trong một Web User Control hoặc trong một lớp khác thì cần phải đăng ký với Ajax.NET như sau.

Khai báo đăng ký Ajax.NET cho Web User Control, trong đó WebUserControl1 là tên của lớp user control có các hàm sử dụng Ajax:

AjaxPro.Utility.RegisterTypeForAjax(typeof(WebUser Control1), this.Page);
Khai báo đăng ký với Ajax.NET cho lớp Class1 có các hàm sử dụng Ajax:

AjaxPro.Utility.RegisterTypeForAjax(typeof(Class1) );
Tương tự, nếu kiểu dữ liệu trả về là một đối tượng tự xây dựng thì ta cũng phải đăng ký như Class1 ở trên.

Như đã đề cập ở phần trên của bài viết, có một số hạn chế khi xây dựng các hàm Ajax để gọi từ phía client cần phải chú ý:

• Để truy cập các biến Request, Response, Session, Cache... cần phải sử dụng thông qua biến HttpContext.Current.

• Nếu muốn hàm Ajax sử dụng các biến lưu trong session thì phải chỉ rõ khi khai báo thuộc tính AjaxMethodAttribute. Ví dụ hàm CheckAvailablity ở trên cần phải được khai báo đúng như sau:

AjaxPro.AjaxMethod(AjaxPro.HttpSessionStateRequire ment.Read)]

public bool CheckAvailablity(string userName)
{
return (null == Session[userName]);
}

Trong đó HttpSessionStateRequirement là một enum định nghĩa các kiểu truy nhập vào biến session mà hàm CheckAvailability sẽ sử dụng.

• Khi hàm Ajax được gọi sẽ không phát sinh ra sự kiện postback ở phía server, do đó hàm xử lý sự kiện Page_Load cũng sẽ không được gọi, và hàm Ajax không thể truy cập các control có trên trang web (server control).

Ứng dụng đơn giản trên chỉ là minh hoạ cho việc sử dụng thư viện Ajax.NET với ASP.NET, còn nhiều tính năng nữa của thư viện này chưa trình bày được trong phạm vi bài viết như caching, hỗ trợ chuyển đổi kiểu dữ liệu, context... Bạn có thể tự tìm hiểu chi tiết sau khi đã làm quen với thư viện này.

Lời kết

Bản thân Ajax là một khái niệm mới và thư viện Ajax.NET vẫn đang còn được phát triển, nên còn một số hạn chế cũng như những thiếu sót trong tài liệu. Tuy nhiên nếu yêu cầu của ứng dụng không quá phức tạp thì nó hoàn toàn có thể đáp ứng tốt, giúp lập trình viên giảm đáng kể công sức so với sử dụng trực tiếp đối tượng XMLHttpRequest. Thậm chí chúng ta có thể sửa đổi mã nguồn của thư viện này để đáp ứng yêu cầu riêng của mình nếu cần thiết. Nếu gặp vấn đề trong khi sử dụng thư viện này, bạn đọc có thể tham gia vào nhóm thảo luận Ajax.NET tại http://groups.google.com/group/Ajaxpro để tìm thông tin trợ giúp cũng như chia sẻ kinh nghiệm của mình.