Cấu trúc ASP.NET 2.0
ASP.NET 2.0 sẽ cung cấp các cơ cấu để thực hiện phương pháp phát triển tương tự Visual Basic, như là cơ cấu sinh ra event từ postback, HTTP request, và các control được biểu hiện bằng thẻ, hay cơ cấu maintain trạng thái theo ViewState.
Hoạt động của Visual Basic Applciation
Trước tiên, chúng ta cùng suy nghĩ về những hoạt động của Visual Basic Applciation. Theo như hiển thị dưới đây, thì trong Visual Basic Application form là tất cả phần trung tâm.
-
Tạo form rồi hiển thị.
-
Khi user thao tác form thì event handler được gọi ra.
-
Event handler thực hiện logic, set peroperty của control, rồi load lại màn hình.
-
Lặp lại 2-3.
-
Tạo và hiển thị form mới nếu cần.
-
Lặp lại 2-5.
Nếu so sánh với hoạt động của Web application thì chắc các bạn sẽ hiểu được sự khác biệt giữa chúng. Sau đây là 3 điểm khác biệt cụ thể.
-
Trong Visual Basic có thể thao tác nhiều lần với cùng 1 form.
-
Trong Visual Basic thì không phải là lần nào cũng tạo ra HTML mới mà chỉ thay đổi 1 form.
-
Visual Basic là stateful.
Control mà được hiển thị bằng thẻ
Web application và Visual Basic không phải là khác nhau hoàn toàn. Cả HTML sử dụng trên Web application và *.frm biểu thị form của Visual Basic đều có điểm chung là cả 2 đều là cấu trúc cây (mặc dù hoàn toàn không có điểm chung về mặt ngữ pháp). Có form, trong đó có panel (trong HTML là thẻ <div> và thẻ <table>), có text box, button. Tất cả những cái này được gọi là các control biểu thị phần GUI, vì thế nó sẽ có cấu trúc cây, với hình thức như Composite pattern, ở chỗ gọi là design pattern.
Vì thế nên trong ASP.NET có nhiều control với hình thức giống HTMLthẻ trong HTML. Chúng tôi xin được đưa ra source code cụ thể như sau.
<form id="form1" runat="server">
<p>
HonoricTitle:
<asp:DropDownList ID="honorificTitleDropDownList" runat="server">
<asp:ListItem Text="Mr." Value="1" />
<asp:ListItem Text="Mrs." Value="2" />
<asp:ListItem Text="Miss" Value="3" />
</asp:DropDownList>
</p>
<p>
Name:
<input type="text" name="nameTextBox" runat="server" />
</p>
<p>
<asp:Button ID="sendDataButton" Text="Send Data to
Application Server" runat="server" />
</p>
</form>
Thẻ mà giá trị của thuộc tính runat được set bằng "server" là control của ASP.NET 2.0. Trong trường hợp tên thẻ bắt đầu bằng "asp:" thì sử dụng control có tên giống với thẻ ở namespace của System.Web.UI.WebControls, các trường hợp khác thì sử dụng control có tên giống với thẻ của HTML ở namespace của System.Web.UI.HtmlControls. Những control này sẽ sinh ra HTML phù hợp khi chạy thông qua runtime của ASP.NET 2.0. Ví dụ trong trường hợp <asp:DropDownList> thì sẽ sinh ra <select>.
Post back
Vì những điểm giống nhau đã kết thúc bằng control biểu thị bằng thẻ nên bây giờ chúng ta sẽ đi sâu vào những điểm khác biệt.
Điểm khác biệt mà chúng ta có thể nghĩ ngay tới chính là nơi gửi request. Do trong Visual Basic thì có thể thực hiện nhiều lần event handler trong những màn hình giống nhau nên không thể tiến hành gửi request tới màn hình tiếp theo như ở Web application thông thường. Mà bắt buộc phải tự gửi lại cho chính mình.
Trong ASP.NET 2.0 gọi việc gửi thông tin request lại cho chính mình được gọi là postback. Về nguồn gốc tên postback nghĩa là việc gửi thông tin request trong Web application như đã trình bày chính là protocol POST của HTTP, và nó sẽ trả lại request đó cho component đã sinh ra HTML.
Cách làm cụ thể để thực hiện post back?
Phương pháp thực hiện post back thì rất đơn giản, chỉ là thao tác đưa URL của chính mình vào thuộc tính action của thẻ <form> để hiển thị form trên HTML. Nếu nhìn vào source code của ASP.NET 2.0 như đã đưa ra thì các bạn sẽ thấy là trong <form> không có thuộc tính action. Vì trong <form> có runat="server" nên nó chính là control của ASP.NET 2.0. Control <form> này sẽ tự động sinh ra thuộc tính action để trỏ vào chính mình khi tạo ra HTML, và thực hiện postback.
Tạo event từ HTTP request
Theo như đã trình bày ở phần "HTTP là gì?" thì request mà gửi thông tin lại cho chính mình bằng postback vô cùng đơn giản.
Để tương ứng với Visual Basic, phải thực hiện chuyển request này thành 1 dạng event nào đó, và cuối cùng các method như sendButton_Click(object source, EventArgs e) phải được gọi ra.
Cách làm cụ thể để tạo event từ HTTP request?
Những thao tác khó sẽ được thực hiện bởi JavaScript (cụ thể là sẽ sinh ra hàm JavaScript có tên __doPostBack) của client site chỉ được sinh ra trong trường hợp logic của runtime ASP.NET 2.0 sử dụng tính năng HTTP request, mà logic của runtime không thể thực hiện được.
Maintain trạng thái theo ViewState
Nếu chỉ sử dụng HTTP một cách thông thường và hiển thị ra thì việc sinh ra event từ HTTP như đã trình bày ở trên là rất khó khăn. Bởi vì HTTP là stateless.
Trong HTTP giữa request trước và request sau này không có quan hệ gì. Cho dù có request được gửi thông tin từ Web browser giống nhau của cùng một computer thì nó cũng không có quan hệ gì cả. Hơn nữa thậm chí là việc tạo event của change series (ví dụ TextChanged) là vô cùng khó khăn.
Chúng ta sẽ cùng đi vào nội dung cụ thể hơn. Trong server site dựa theo HTTP request mà chỉ có thể nhận thông tin của input data, thì cho dù hiểu được nội dung đã input thì vẫn không hiểu được nội dung đã hiển thị trước đó.
Nếu là stateful, có thể hiểu được lần trước đã trả response như thế nào, thế nhưng tiếc là HTTP lại là stateless. Vì thế, cho dù hiều được input là "XX" lần này thì vẫn không hiểu được trước cái đó là "YY" hay là "ZZ". Vì thế nên từ HTTP request thông thường không thể sinh ra event của change series.
Trong HTTP, rất khó để maintain property of control
Chúng ta hãy cùng nhau suy nghĩ sâu hơn nào. Lấy ví dụ về label là control của Visual Basic. Label control là control sẽ hiển thị lên màn hình các character đã được set bởi Text property, và nó được biểu hiện bằng sử dụng thẻ <span> của HTML. Nó không phải là thẻ <input>. Vì thế nên trong HTTP request không bao gồm data của label control.
Hơn nữa, như đã trình bày ở phần trước, HTTP là stateless, nên không biết được ở lần response trước nó trả lại HTML như thế nào? Vì thế, trừ khi có các solution đặc biệt, còn không thì sẽ không thể hiển thị được gì trên Web browser cả trong response trước và sau này.
Nếu như vậy thì chúng ta vẫn chưa thể thực hiện tương đương với Visual Basic. Do vậy bằng cách nào đấy chúng ta buộc phải giữ lại trạng thái trước đó và trong request phải bao gồm cả thông tin liên quan đến trạng thái trước đó.
Cách làm cụ thể để giữ trạng thái theo ViewState?
Thật may, nếu sử dụng thẻ <input type=”hidden”> thì việc add thêm thông tin tới cho request rất đơn giản. Gọi là thẻ <input type=”hidden”> là bởi vì nó là input item không được hiển thị lên màn hình theo đúng như tên gọi của nó, mà sẽ gửi các giá trị đã được chỉ định bằng thuộc tính value.
Trong ASP.NET 2.0, sử dụng thẻ <input type=”hidden”> thì có thể giữ được trạng thái trước đó. Cụ thể là sẽ tạo ra thẻ <input type=”hidden”> mà thuộc tính name được set trong "__VIEWSTATE", để giữ lại trạng thái control chứa trong form vào trong thẻ đó. Trong ASP.NET 2.0 người ta gọi tính năng lưu giữ lại trạng thái bằng phương thức này là ViewState.
Hoạt động của ASP.NET 2.0
Chúng ta sẽ tóm tắt lại những phần trên và trình bày về hoạt động của ASP.NET 2.0. Phần trình bày sẽ dựa trên việc phân chia thành request lần đầu và request từ lần 2 trở đi.
Trường hợp request lần đầu
Nếu ASP.NET 2.0 nhận request HTTP từ Web browser, thì nó sẽ tạo ra form instance. Form instance sẽ tạo ra cây của control instance ở bên trong đó.
Sau đó, cho khởi động Load event, và gọi ra event handler mà chúng ta sẽ tạo. Trong event handler, set property của control trong control cây để kiểm soát việc hiển thị màn hình.
Cuối cùng, Form sẽ sinh ra HTML và trả về Web browser. Xử lí generate HTML được chuyển đến control, control sẽ sinh ra HTML phù hợp với property của chính mình. Hơn nữa, có thể lưu giữ trạng thái của control vào trong ViewState khi cần, và thẻ <input type=”hidden”> sẽ được tạo ra.
Trường hợp request từ lần 2 trở đi
Nội dung cho đến phần nhận request HTTP, tạo cây của form instance và control instance thì giống với request đầu tiên.
Trong postback request bao gồm ViewState tạo trong response trước đó, vì thế sẽ set control property giống như khi trả về response lần trước dựa vào ViewState đó.
Sau đó, so sánh trạng thái giữa HTTP request và trạng thái control hiện tại (được phục hồi nhờ ViewState), thì chúng ta sẽ khởi động event thích hợp. Do form được load tương tự với trường hợp request đầu tiên, nên đầu tiên, load event nếu giá trị được input vào textbox khác với ViewState, và nếu TextChanged event, button được click, thì chúng ta cảm giác như là Clicked event.
Đương nhiên, với các event handler của load event mà cả request đầu tiên, cả postback (Page_Load() method) đều được gọi ra vô điều kiện thì sử dụng IsPostBack property biểu thị là có postback hay không, để thay thế nội dung xử lí. Hãy lấy ví dụ cụ thể. Thông thường Page_Load() method sẽ như sau.
private void Page_Load(object sender, EventArgs e)
{
// Sử dụng IsPostBack property, phán đoán xem có postback hay không?
if (!IsPostBack)
{
// ở đây sẽ mô tả xử lí khởi tạo.
}
// Ở đây sẽ mô tả xử lí chung trong tất cả event.
}
Các request sau giống với request đầu tiên. Control sẽ tạo ra HTML, và ViewState lưu giữ trạng thái sẽ được sinh ra.
[Usol VN]