Giới thiệu
Cho đến thời điểm này chúng ta chỉ mới tạo được một website tĩnh, với dữ liệu (nội dung, bố cục, menu, v.v.) được thêm vào trang một cách cố định. Tuy nhiên, chúng ta có thể tạo ra một website hấp dẫn hơn bằng cách kết hợp các dữ liệu động. Các dữ liệu động này có thể đến từ server (các files, databases, v.v.) hay đến từ người dùng nhập từ web browser và gửi trở lại server – phổ biến nhất là nhập dữ liệu từ một webform và submit nó đến server.
Để ngăn chặn những dữ liệu không hợp lệ, điều đầu tiên là phải hợp lệ hoá những dữ liệu trước khi cho phép hệ thống website làm việc với chúng. ASP.NET 4.X cung cấp cho chúng ta một bộ các công cụ để làm nhiệm vụ này một cách đơn giản nhất. Chương này sẽ tìm hiểu về chúng và một số kĩ thuật có ích khác.
Thu thập dữ liệu người dùng
Dữ liệu người dùng có thể được gửi đến server bằng nhiều cách, phổ biến nhất là dùng phương thức GET và POST.
Với GET, chúng ta dùng chuỗi truy vấn (xem lại cuối chương VII – phần Lập trình chuyển trang) bằng thuộc tính QueryString của đối tượng Request. Ví dụ chúng ta có URL kèm theo chuỗi truy vấn như sau:
http://www.PlanetWrox.com/Reviews/ViewDetails.aspx?ReviewId=34&CategoryId=3
Có thể truy cập đến các thành phần của chuỗi truy vấn này, ví dụ ReviewId hay CategoryId, bằng phương thức GET của collection QueryString (lưu ý đây là collection chứ không phải thuộc tính như trên) như sau:
' Gán giá trị của ReviewId (34) đến biến reviewId Dim reviewId As Integer = Convert.ToInt32(Request.QueryString.Get("ReviewId")) ' Gán giá trị CategoryId (3) đến biến categoryId Dim categoryId As Integer = Convert.ToInt32(Request.QueryString.Get("CategoryId"))
Mã C#
int reviewId = Convert.ToInt32(Request.QueryString.Get("ReviewId")); int categoryId = Convert.ToInt32(Request.QueryString.Get("CategoryId"));
Với POST, không cần đến chuỗi truy vấn, mà lấy dữ liệu trực tiếp từ form thông qua các controls. Ví dụ, chúng ta có một form gồm một textbox gọi là Age (thuộc tính ID) dùng để nhập tuổi người dùng và một button dùng để submit tuổi người dùng đến server, trong sự kiện Click của button có thể viết dòng code như sau:
' gán tuổi người dùng (từ textbox Age) đến biến age Dim age As Integer = Convert.ToInt32(Age.Text)
Mã C#
int age = Convert.ToInt32(Age.Text);
Sẽ không vấn đề gì nếu người dùng nhập dữ liệu hợp lệ, như 30 chẳng hạn, nhưng nếu người dùng, thay vì nhập một số sẽ nhập một chuỗi, như I am 30 chẳng hạn, thì phương thức ToInt32 sẽ báo lỗi bằng cách phát sinh một ngoại lệ.
Như vậy, chúng ta cần phải có một cách nào đó để kiểm tra (hay hợp lệ hoá) các dữ liệu được nhập bởi người dùng. Chúng ta có thể viết vài đoạn code (snippets), bằng các ngôn ngữ hướng client như JavaScript, để kiểm soát người dùng ngay tại trình duyệt web, nhưng một vài người dùng am hiểu kĩ thuật, hacker chẳng hạn, có thể dễ dàng vô hiệu hoá các đoạn mã JavaScript viết trực tiếp tại trình duyệt, dễ dàng vượt qua các rào cản và gửi dữ liệu nguy hiểm đến server.
ASP.NET cung cấp một loạt các validation controls để giúp chúng ta kiểm soát dữ liệu người dùng ngay tại server, cụ thể là 6 validation controls với 5 trong số chúng thực hiện công việc xử lí dữ liệu người dùng và control thứ 6 – ValidationSumamary – dùng để cung cấp một cảnh báo đến người dùng nếu lỗi xảy ra.
Điểm tuyệt vời nhất của các validation controls là chúng có thể kiểm tra dữ liệu người dùng tại cả client lẫn server. Khi thêm một validation control vào trang, control sẽ sinh ra một đoạn mã JavaScript để kiểm tra dữ liệu người dùng tại trình duyệt web, đồng thời kiểm tra dữ liệu người dùng tại server một cách tự động. Với các validation control, hệ thống website của chúng ta sẽ được bảo vệ bởi hai tầng (client – server).
Làm quen các validation controls
Để hiểu cách dùng các validation controls chúng ta sẽ thực hiện bài thực hành sau. Các controls này chứa trong mục Validation của thanh Toolbox
Thực hành dùng RequiredFieldValidator control
Trong phần thực hành này chúng ta sẽ tạo ra một user control gọi là ContactForm.ascx. Chúng ta có thể đặt nó trong một trang web để người dùng nhập một vài thông tin đơn giản, trong phần thực hành sau chúng ta sẽ mở rộng user control để cho phép người dùng gửi thông tin đến tài khoản e-mail của bạn.
- Thêm một user control tên ContactForm.ascx đến thư mục Controls (có thể xem lại cách tạo Banner.ascx ở chương VIII).
- Chuyển ContactForm.ascx sang chế độ Design. Vào Table > Insert Table để tạo một bảng 8 hàng 3 cột.
- Bôi đen 3 ô hàng đầu tiên, nhấp chuột phải chọn Modify > Merge Cells để nhập 3 ô thành một. Trong ô mới này, chúng ta có thể gõ vài thông tin đến người dùng.
- Tại hàng thứ hai, ô đầu tiên gõ từ Tên, ô thứ hai chứa một textbox được kéo từ Toolbox với ID là Name, ô thứ ba chứa RequireFieldValidator được kéo từ mục Validation của Toolbox. Tại hàng cuối cùng, ô thứ hai chúng ta thêm một button với thuộc tính Text là Send và ID là SendButton. Giao diện lúc này như sau:
- Chọn RequireFieldValidator và mở hộp thoại Properties để thiết lập một số thuộc tính sau:
- Lưu tất cả và đóng ContactForm.ascx .
- Thêm đoạn css sau vào file Monochrome.css và DarkGrey.css và lưu lại:
.ErrorMessage { color: Red; }
- Mở trang Contact.aspx trong thư mục About ở chế độ Source, kéo ContactForm.ascx từ thư mục Control trong cửa sổ Solution Explorer và thả vào vùng cpMainContent:
VS sẽ dùng lại ngocminhtran (TagPrefix) đã được khai báo khi chúng ta tạo Banner.ascx.
- Mở Web.config, trong <configuration> thêm phần tử <appSettings> kèm phần tử con của nó là <add>, mục đích là để vô hiệu chức năng đòi hỏi jQuery (sẽ được thảo luận chương sau):
- Lưu tất cả. Chọn trang Contact.aspx và Ctrl + F5. Để textbox rỗng và nhấn nút Send sẽ xuất hiện dấu * màu đỏ bên phải:
- Nhập thông tin vào textbox và nhấn Send, trang gửi thành công đến server và dấu * đỏ biến mất:
Dùng các kiểu dữ liệu HTML5
HTML5 giới thiệu một số kiểu mới cho thuộc tính type của phần tử input.
Các kiểu mới cho phép chúng ta quyết định cách trình duyệt web hiểu trường dữ liệu như thế nào. ASP.NET 4.X cung cấp các kiểu mới của HTML5 thông qua thuộc tính TextMode của Textbox. Những kiểu cũ đã được hỗ trợ trong ASP.NET 1.0 như SingleLine, MultiLine hay Password vẫn giữ nguyên, bên cạnh đó là một vài kiểu mới sau:
Thuộc tính | Mô tả |
Color | Cho phép người dùng chọn màu sắc, thường là từ color picker. |
Date/DateTime/
DateTimeLocal/ Month/Week/Time |
Cho phép người dùng nhập date hay time theo nhiều cách khác nhau. |
Cho phép nhập một địa chỉ email. | |
Url | Cho phép nhập địa chỉ website. |
Number | Cho phép nhập một số. |
Range | Cho phép nhập một số trong một phạm vi nào đó. |
Search | Cho phép người dùng nhập một mục tìm kiếm. |
Các kiểu này là giá trị của thuộc tính TextMode sẽ được chuyển từ server đến trình duyệt với cùng tên nhưng theo dạng chữ thường, ví dụ Email thành emai như sau:
Server
<asp:TextBox runat="server" ID="Email" TextMode="Email" />
Browser
<input name="Email" type="email" id="Email" />
Tuy nhiên, chúng ta cần chú ý khi dùng những kiểu HTML5:
- HTML5 sẽ chỉ hỗ trợ các trình duyệt phiên bản mới
- Sự hỗ trợ các kiểu HTML5 cho các trình duyệt khác nhau là khác nhau.
- Những kiểu mới sẽ không an toàn cho việc hợp lệ hoá dữ liệu.
Các validation controls chuẩn
Các validation controls chứa trong mục Validation của Toolbox. Các controls này đều được xây dựng sẵn các tập luật phục vụ việc hợp lệ dữ liệu người dùng, trừ control cuối cùng, CustomValidator, cho phép chúng ta bổ sung thêm các luật theo mục đích riêng.
Các validation controls chia sẻ chung các thuộc tính sau
Thuộc tính | Mô tả |
Display | Cho phép hiển thị thông điệp lỗi, rất có ích khi dùng ValidationSummary. |
CssClass | ứng dụng lớp css đến thông điệp lỗi. |
ErrorMessage | Thông điệp lỗi dùng trong ValidationSummary. Khi thuộc tính Text rỗng, giá trị của thuộc tính này sẽ thay thế. |
Text | Lưu trữ text mà control sẽ hiển thị trên trang. |
ControlToValidate | Chứa ID của control cần hợp lệ. |
EnableClientScript | Quyết định liệu control có cung cấp cơ chế hợp lệ tại trình duyệt hay không (một đoạn JavaSript chẳng hạn). Mặc định là True. |
SetFocusOnError | Xác định liệu script (client) cho một focus đến control đầu tiên phát sinh lỗi. Mặc định là False. |
ValidationGroup | Có thể nhóm các validation controls lại cùng nhau, quá trình hợp lệ sẽ diễn ra tại cùng một thời điểm cho tất cả các control trong nhóm. |
IsValid | Không thể thiết lập giá trị tại thời điểm thiết kế (design time), nhưng tại thời điểm thực thi (run time), nó cung cấp thông tin liệu quá trình hợp lệ có thành công không. |
Chúng ta đã tìm hiểu cách dùng RequiredFieldValidator ở bài thực hành trên. Phần kế tiếp chúng ta sẽ tìm hiểu các controls còn lại.
RangeValidator
Cho phép kiểm tra một giá trị có thuộc phạm vi cho phép hay không. Một số thuộc tính cơ bản (bên cạnh các thuộc tính chung đã nêu trên):
Thuộc tính | Mô tả |
MinimumValue | Cho phép giá trị hợp lệ thấp nhất. |
MaximumValue | Cho phép giá trị hợp lệ cao nhất. |
Type | Xác định kiểu dữ liệu của giá trị cần kiểm tra (Date, String, Integer, v.v.) |
Ví dụ đảm bảo giá trị nhập vào textbox Rate là một số nguyên từ 1 đến 10:
<asp:RangeValidator ID="RangeValidator1" runat="server" ControlToValidate="Rate" ErrorMessage="Nhập một số giữa 1 và 10" MaximumValue="10" MinimumValue="1" Type="Integer" />
RegularExpressionValidator
Cho phép kiểm tra tính hợp lệ các dữ liệu phức tạp như địa chỉ email, ZIP code, v.v. Các luật cho các dữ liệu này được thiết lập dựa trên biểu thức thường quy (regular expression). Ví dụ kiểm tra tính hợp lệ một địa chỉ email:
<asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" ControlToValidate="Email" ErrorMessage="Nhập một email hợp lệ" ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" />
CompareValidator
Dùng để so sánh giá trị của một control với giá trị một control khác. Chúng ta có thể thấy điều này trong form đăng nhập, phần xác nhận mật khẩu. Một số thuộc tính cơ bản (bên cạnh các thuộc tính chung ở trên):
Thuộc tính | Mô tả |
ControlToCompare | Chứa ID của control muốn so sánh. |
Operator | Xác định toán tử so sánh (Equal, NotEqual, v.v.) |
Type | Xác định kiểu dữ liệu (String, Integer, v.v.) |
ValueToCompare | So sánh với giá trị hằng được định nghĩa trước. |
Ví dụ đảm bảo hai textbox có cùng password:
<asp:CompareValidator ID="CompareValidator1" runat="server" ControlToCompare="ConfirmPassword" ControlToValidate="Password" ErrorMessage="Your passwords don't match" />
Thực hành dùng validation controls
Trong bài thực hành này chúng ta sẽ mở rộng ContactForm bằng cách thêm các trường để người dùng cung cấp thêm thông tin về địa chỉ email, số điện thoại cá nhân hay cơ quan và một vài ghi chú. Địa chỉ email để đảm bảo chính xác phải được nhập hai lần, số điện thoại phải được nhập ít nhất một trong hai số.
- Mở file ContacForm.ascx trong thư mục Controls ở chế độ Design.
- Kéo 5 textbox từ Toolbox và thả vào 5 ô ở cột thứ hai, giữa textbox nhập tên và nút Send. Thiết lập ID các textbox từ trên xuống lần lượt là EmailAddress, ConfirmEmailAddress, PhoneHome, PhoneBusiness, Comments.Thêm vài đoạn text ở các ô cột đầu tiên mô tả từng text box vừa thêm vào. Thiết lập thuộc tính TextMode của textbox Comments là MultiLine và mở rộng textbox này thêm để tiện cho người dùng nhập thông tin. Thiết lập thuộc tính TextMode của EmailAddress và ConfirmEmailAddress là Email. Giao diện trông như sau:
- Trên hàng Địa chỉ Emai, tại ô cuối cùng, kéo và thả vào một RequiredFieldValidator và một RegularExpressionValidator; trên hàng Xác nhận địa chỉ Email, tại ô cuối cùng, kéo và thả vào một RequiredFieldValidator và một CompareValidator. Cuối cùng, tại ô cuối cùng của hàng Chú thích, kéo và thả một RequiredFieldValidator:
- Chọn tất cả validation controls vừa thêm vào (RequiredFieldValidator, RegularExpressionValidator , CompareValidator) một lần (chọn một control, nhấn phím Ctrl và chọn các controls khác) và vào hộp thoại Properties thiết lập thuộc tính Text là dấu *, thuộc tính Display là Dynamic, thuộc tính, và CssClass là ErrorMessage.
- Các thuộc tính còn lại của các validation controls được thiết lập như sau:
Control | Thuộc tính | Giá trị |
RequiredFieldValidator (cho Địa chỉ Email) | ErrorMessage | Nhập địa chỉ Email |
ControlToValidate | EmailAddress | |
RegularExpressionValidator | ErrorMessage | Nhập địa chỉ Email hợp lệ |
ControlToValidate | EmailAddress | |
ValidationExpression | Nhấp vào nút bên phải và chọn Internet e-mail address | |
RequiredFieldValidator (cho Xác nhận địa chỉ Email) | ErrorMessage | Xác nhận địa chỉ Email |
ControlToValidate | ConfirmEmailAddress | |
CompareValidator | ErrorMessage | Email không khớp nhau |
ControlToCompare | EmailAddress | |
ControlToValidate | ConfirmEmailAddress | |
RequiredFieldValidator (cho Chú thích) | ErrorMessage | Nhập một chú thích |
ControlToValidate | Comments |
- Lưu và đóng ContactForm.ascx. Chọn trang Contact.aspx từ thư mục About và Ctrl + F5. Để trống các textbox và bấm Send:
- Nhập Email sai định dạng:
- Nhập email không khớp nhau:
- Nhập phù hợp:
Bài thực hành trên dùng các validation controls để cảnh báo người dùng khi nhập thiếu thông tin hay nhập sai định dạng thông tin nhưng vẫn chưa có những thông báo chỉ dẫn cụ thể, rõ ràng. Chúng ta sẽ làm điều này nhờ CustomValidator và ValidationSummary.
CustomValidator cho phép bạn viết các chức năng kiểm tra tính hợp lệ dữ liệu người dùng ở client (JavaScript) và server (C# hay VB). ValidationSummary cung cấp cho người dùng một danh sách các lỗi nhận được từ thuộc tính ErrorMessage của các controls. Các lỗi này có thể được hiển thị theo 3 cách: nhúng trực tiếp danh sách vào trang, dùng phương thức alert trong JavaScript hay kết hợp cả hai cách. Các thuộc tính quan trọng của ValidationSummary là ShowMessageBox, ShowSummary, DisplayMode. Chúng ta sẽ hiểu hơn về hai controls này qua bài thực hành sau đây.
Thực hành dùng CustomValidator và ValidationSummary
Chúng ta dùng CustomValidator trong trang để đảm bảo ít nhất một trong hai số điện thoại phải được nhập. Dùng ValidationSummary để cung cấp phản hồi các lỗi cho người dùng.
- Mở ContactForm.ascx ở chế độ Design, chọn hàng cuối cùng của bảng (chứa nút Send) và kích chuột phải chọn Insert > Row Below để thêm một hàng mới. Khi xuất hiện hàng mới, chọn cả 3 ô của hàng mới này và nhấp chuột phải chọn Modify > Merge Cells để trộn 3 ô thành 1.
- Kéo một ValidationSummary từ mục Validation của Toolox và thả vào hàng cuối với một ô duy nhất vừa tạo. Thiết lập thuộc tính CssClass đến ErrorMessage.
- Kéo một CustomValidator và thả vào ô trống (ô cuối cùng) sau textbox Số điện thoại cá nhân. Thiết lập các thuộc tính đến các giá trị như sau:
Thuộc tính | Giá trị |
CssClass | ErrorMessage |
Display | Dynamic |
ErrorMessage | Nhập số điện thoại cá nhân hay số cơ quan |
Text | * |
ClientValidationFunction | validatePhoneNumbers (là một phương thức JavaScript) |
- Nhấp đôi chuột vào CustomValidator để đến trình xử lí sự kiện ServerValidate và thêm một vài đoạn mã sau:
Mã C#
if (!string.IsNullOrEmpty(PhoneHome.Text) ||!string.IsNullOrEmpty(PhoneBusiness.Text)) { args.IsValid = true; } else { args.IsValid = false; }
- Chuyển ContactForm.ascx đến chế độ Source và thêm đoạn mã JavaScript của phương thức validatePhoneNumbers (trong cặp thẻ <script>) phía trên thẻ <table> như sau:
- Lưu tất cả và đóng ContactForm.ascx . Chọn trang Contact.aspx và Ctrl + F5, bấm nút Send:
- Mở lại ContactForm.ascx ở chế độ Design, chọn ValidationSummary và thiết lập thuộc tính ShowMessageBox đến True và ShowSummary đến False. Thiết lập HeaderText đến Xin hãy nhập đầy đủ thông tin bên dưới:
- Lưu và mở lại trang Contact.aspx, Ctrl + F5 và bấm nút Send sẽ xuất hiện hộp thoại cảnh báo sau:
Yêu cầu hợp lệ (request validation)
Mặc định, các controls trong trang ASP.NET sẽ không cho phép nhập nội dung là các đoạn mã HTML hay các script, ví dụ nhập đoạn mã <h1> Hello </h1> vào textbox Chú thích thì trang ASP.NET sẽ phát sinh một ngoại lệ như sau:
Mục đích là để ngăn chặn người dùng nhập những đoạn mã độc hại gây nguy hiểm cho hệ thống website. Tuy nhiên, trong một vài trường hợp chúng ta cho phép người dùng nhập các đoạn mã HTML hay các script. Muốn làm điều này, ví dụ với trang Contact.aspx, chúng ta tìm đến <%@ page> ở đầu trang và thiết lập thuộc tính ValidateRequest đến False và lúc này nếu nhập lại đoạn mã HTML sẽ không còn lỗi.
Tuy nhiên, nếu dùng cách này thì mọi controls trong trang đều cho phép người dùng nhập đoạn mã HTML hay Script và chúng ta chỉ muốn một vài controls cho phép nhập, một vài controls khác thì không. ASP.NET 4.5 cung cấp thuộc tính ValidateRequestMode cho các controls. Thuộc tính này có 3 giá trị là Enabled không cho phép nhập mã HTML hay Script, Disable cho phép nhập HTML hay Script và Inherit kế thừa giá trị của control cha như PlaceHolder (trong trường hợp chúng ta nhóm các control trong một PlaceHolder).
Đọc nội dung từ tập tin văn bản (text files)
.NET Framework cung cấp nhiều lớp và phương thức cho phép làm việc dễ dàng với các tập tin. Với các tập tin văn bản, lớp File chứa trong namespace System.IO được dùng phổ biến. Lớp File chứa các phương thức sau:
Phương thức | Chức năng |
AppendAllText | Thêm một chuỗi kí tự đến một file văn bản. Nếu file văn bản này chưa tồn tại thì phải tạo ra nó đầu tiên. |
Copy | Sao chép một tập tin từ một vị trí đến vị trí khác. |
Delete | Xoá một tập tin từ nơi ổ đĩa lưu trữ. |
Exists | Kiểm tra một file có tồn tại hay không. |
Move | Di chuyển file đến vị trí khác. |
ReadAllText | Đọc nội dung của một tập tin văn bản. |
WriteAllText | Ghi nội dung đến một file mới, ghi đè lên nội dung đã có nếu file đã tồn tại. |
Chúng ta sẽ hiểu hơn lớp File và các phương thức của nó thông qua phần thực hành sau.
Thực hành với tập tin văn bản
- Tạo một thư mục mới tên App_Data trong Site. Thêm một tập tin văn bản tên txt bằng cách nhấp chuột phải vào App_Data chọn Add > Add New Item > Text File, gõ tên file là Text.txt và nhấn Add.
- Trong trong Text.txt gõ nội dung sau, lưu ý rằng có các chuỗi được chứa trong cặp ## gọi là các PlaceHolder dùng để chứa nội dung của các textbox :
- Lưu và đóng Text.txt. Mở file ContactForm.ascx.vb chèn thêm namespace System.IO bằng lệnh Imports hàng đầu tiên:
- Mở file ContactForm.ascx ở chế độ Source, thêm các thuộc tính runat và id vào <table>. Bằng cách này, table đã trở thành một server control và sẽ ẩn khi xem ở client (trình duyệt web)
- Tìm đến vị trí dưới </table>, thêm một Label với các thuộc tính như sau:
- Mở ContactForm.ascx ở chế độ Design, nhấp đôi chuột vào nút Send để đến sự kiện Click và viết vài dòng mã sau:
Mã C#
if (Page.IsValid) { string fileName = Server.MapPath("~/App_Data/Text.txt"); string MessageBody = File.ReadAllText(fileName); MessageBody = MessageBody.Replace("##Name##", Name.Text); MessageBody = MessageBody.Replace("##Email##", EmailAddress.Text); MessageBody = MessageBody.Replace("##HomePhone##", PhoneHome.Text); MessageBody = MessageBody.Replace("##BusinessPhone##", PhoneBusiness.Text); MessageBody = MessageBody.Replace("##Comments##", Comments.Text); Message.Visible = true; Message.Text = MessageBody; FormTable.Visible = false; }
- Lưu. Chọn trang Contact.aspx và Ctrl + F5, gõ một vài thông tin vào Form và bấm Send:
Kết quả sau khi nhấn Send:
Ý kiến bài viết