Một website được thiết kế tốt nếu nó có một hệ thống điều hướng tốt – gồm các khía cạnh như hệ thống menu (thực đơn), cấu trúc website hay khả năng chuyển từ trang này sang trang khác một cách hợp lý. Với một hệ thống điều hướng tốt, người dùng sẽ dễ dàng tìm được thông tin mình cần. Hệ thống điều hướng gồm nhiều thành phần, thành phần đơn giản nhất là menu (thực đơn). Menu có thể chỉ là các liên kết HTML đơn giản (thẻ a) hay có thể là phức tạp hơn khi kết hợp với các kĩ thuật CSS hay JavaScript (hay jQuery). ASP.NET 4.5 cung cấp một danh sách các controls cho phép tạo một hệ thống điều hướng nhanh chóng và hiệu quả như Menu, TreeView, và SiteMapPath. Ngoài ra, như đã nêu trên, một hệ thống điều hướng tốt đòi hỏi phải có cấu trúc tốt và khả năng chuyển các trang một cách hiệu quả – điều này đòi hỏi khả năng thiết kế và tư duy hệ thống của người thiết kế.

Trong chương này chúng ta sẽ học cách để tạo một hệ thống điều hướng với ASP.NET 4.5.

Điều hướng đơn giản với các siêu liên kết

Cách đơn giản nhất giúp người dùng chuyển từ trang này sang trang khác trong website của bạn là sử dụng thẻ a. Ví dụ muốn chuyển tới trang Login.aspx ta dùng đoạn mã HTML sau:


<a href="Login.aspx">Dang nhap</a>

Khi nhấp chuột vào dòng Dang nhap, người dùng sẽ được chuyển đến trang Login.aspx, trang ở cùng thư mục với trang hiện tại chứa dòng Dang nhap.

Phần tử tương đương với <a> ở phía server là HyperLink và tất nhiên rằng, khi được biên dịch bởi ASP.NET runtime, HyperLink cũng sẽ trở thành <a>. HyperLink có thuộc tính NavigateUrl tương đương với href trong <a>. Đoạn mã minh hoạ HyperLink:


<asp:HyperLink runat="server" id="LoginLink" NavigateUrl="Login.aspx">

    Dang nhap

</asp:HyperLink>

Khi chuyển đến trình duyệt web thì HyperLink sẽ trở thành <a> như sau:


<a id="LoginLink" href="Login.aspx">Dang nhap</a>

Dòng text gán cho thuộc tính href (hay NavigateUrl) gọi là URL (Uniform Resource Locator). URL xác định địa chỉ truy cập tài nguyên (trang web, hình ảnh, video,…) trong hay ngoài website. Gồm hai dạng là URL tương đối (như ví dụ trên) và URL tuyệt đối.

URL tương đối (relative URL)

Là cách thể hiện địa chỉ ngắn gọn đến các tài nguyên của website. Tuy nhiên, để dùng URL tương đối, chúng ta cần chú ý một số điều kiện. Trong ví dụ trên, điều kiện để dùng URL tương đối là trang liên kết đến trang Login.aspx và bản thân trang Login.aspx phải ở trong cùng một thư mục. Để hiểu hơn, giả sử website chúng ta có cấu trúc như sau:

Theo cấu trúc trên, giả sử chúng ta đang mở trang Login.aspx (thứ 3 từ dưới lên trong hình trên) và muốn tạo một liên kết đến trang Default.aspx trong thư mục Management, địa chỉ tương đối cho thuộc tính href của <a> đặt trong trang Login.aspx sẽ là:


<a href= "Management/Default.aspx"> Management </a>

Từ trang Default.aspx trong thư mục Management chúng ta muốn liên kết đến file ảnh Header.jpg, địa chỉ tương đối như sau:


<img src= "../Images/Header.jpg" />

Hai dấu chấm dùng để tham chiếu một thư mục đến thư mục gốc và từ thư mục gốc sẽ tham chiếu trở lại thư mục chứa file ảnh Header.jpg là thư mục Images. Dấu hai chấm có thể được dùng nhiều lần trong địa chỉ tương đối, ví dụ chúng ta muốn liên kết đến file Header.jpg từ trang Default.aspx trong thư mục Reviews (nằm trong thư mục Management) thì địa chỉ như sau:


<img src= "../../Images/Header.jpg" />

Địa chỉ tương đối dựa vào thư mục gốc

Trong ví dụ từ trang Login.aspx liên kết đến trang Default.aspx trong thư mục Management chúng ta dùng địa chỉ tương đối là Management/Default.aspx, tuy nhiên, liên kết sẽ bị lỗi nếu ta di chuyển trang Login.aspx vào một thư mục nào đó (như Members chẳng hạn). Để giải quyết vấn đề này, chúng ta sẽ dùng địa chỉ tương đối dựa vào thư mục gốc (root based relative URL). Để biến một địa chỉ tương đối thành một địa chỉ tương đối dựa vào thư mục gốc, chúng ta chỉ cần thêm dấu “/” vào vị trí đầu tiên, ví dụ Mangement/Default.aspx sẽ thành /Management/Default.aspx. Với địa chỉ tương đối này, một tài nguyên sẽ luôn được liên kết tới từ thư mục gốc. Địa chỉ tương đối dùng trong các server control dùng dấu ~ để trỏ đến thư mục gốc, ví dụ:


<asp:Image ID="Image1" runat="server" ImageUrl= "~/Images/Header.jpg" />

Image tương ứng với img, thuộc tính ImageUrl tương đương src. Image sẽ được ASP.NET run time biên dịch thành img tại trình duyệt web.

URL tuyệt đối (absolute URL)

URL tuyệt đối liên kết đến tài nguyên với một địa chỉ đầy đủ bao gồm cả tên miền và giao thức (http:// hay https://), ví dụ:


<img src="http://p2p.wrox.com/images/header/wrox_logo.gif" />

Địa chỉ tuyệt đối chỉ nên dùng khi liên kết đến tài nguyên bên ngoài website, đối với các tài nguyên trong website (hay dự án) của chúng ta thì nên dùng địa chỉ tương đối vì sự thuận tiện của nó.

Các trang mặc định

Khi chúng ta gõ một URL bất kì trên trình duyệt, ví dụ https://www.microsoft.com, thì một trang web sẽ xuất hiện dù chúng ta không chỉ ra một trang nào cụ thể. Những trang này là những trang mặc định. Với ASP.NET, web server thường cài đặt trang Default.aspx như là trang mặc định (trong PHP, trang mặc định thường là index.php).

Dùng các navigation controls

ASP.NET 4.5 cung cấp ba navigation controls là SiteMapPath, TreeView, và Menu. SitemapPath cung cấp đường dẫn đến trang hiện tại, TreeView hiển thị cấu trúc website và Menu chỉ hiển thị menu Home. Xem hình minh hoạ dưới:

Tập tin Web.sitemap

Các controls như Menu, TreeView hay SiteMapPath có thể hiển thị thông tin về cấu trúc website là nhờ một tập tin XML tên là Web.sitemap, một tập tin mô tả cấu trúc website. Những gì trong tập tin XML này có thể trông như thế này:


<?xml version="1.0" encoding="utf-8" ?>

<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0">

  <siteMapNode url="~/" title="Home" description="Go to the homepage">

    <siteMapNode url="~/Reviews" title="Reviews" description="Reviews published on this site" />

    <siteMapNode url="~/About" title="About" description="About this site" />

  </siteMapNode>

</siteMap>

Tập tin XML cũng gần giống một tập tin HTML, nó cũng bao gồm các thẻ (hay phần tử). Trong ví dụ trên, các thẻ gồm <siteMap>, <siteMapNode> và một tập tin XML bắt đầu bằng <?xml ?> (giống như một tập tin HTML bắt đầu bằng <HTML>). Mỗi thẻ XML, cũng giống HTML, gồm thẻ mở bắt đầu chứa trong dấu “< >” và thẻ kết thúc chứa trong dấu “</ >”, ví dụ <siteMap></siteMap>. Các thẻXML cũng có thể tự đóng, ví dụ <siteMapNode url = “…” title=” ” />; các thẻ XML có thể lồng nhau; trong ví dụ trên <siteMap> chứa <siteMapNode>  và <siteMapNode> lại chứa hai <siteMapNode> khác. Trong các thẻ XML cũng có các thuộc tính, trong ví dụ trên là các thuộc tính như url, title (tiêu đề cho thẻ) hay description (nội dung mô tả của thẻ).

Trước khi học cách sử dụng các Navigation controls, chúng ta sẽ thêm tập tin Web.sitemap vào site.

Thực hành thêm Web.sitemap

  • Nhấp chuột phải vào Site trong cửa sổ Solution Explorer, chọn Add > Add New Item > SiteMap, giữ nguyên tên file là Web.sitemap. Nội dung ban đầu như sau:

  • Chỉnh sửa lại nội dung file Web.sitemap như sau:

  • Lưu lại nội dung file Web.sitemap.

Tập tin Web.sitemap sẽ vô dụng nếu không có các navigation controls sử dụng nó. Phần kế tiếp chúng ta sẽ tìm hiểu các controls như Menu, TreeViewSiteMapPath.

Sử dụng Menu control

Menu rất dễ sử dụng, chỉ cần thêm vào trang và liên kết nó đến SiteMapDataSource control là xong. Dữ liệu trong SiteMapDataSource lấy từ file Web.sitemap. Menu control có nhiều thuộc tính kèm theo nhưng sau đây là bảng danh sách các thuộc tính phổ biến:

Thuộc tính Mô tả
CssClass Cho phép dùng các class CSS.
StaticEnableDefaultPopOutImage Cho phép dùng hình ảnh để xác định menu con từ menu mức cao nhất.
DynamicEnableDefaultPopOutImage Cho phép dùng hình ảnh để xác định menu con từ menu con.
DisappearAfter Khoảng thời gian (mili giây) các items menu xuất hiện sau khi con trỏ chuột rời khỏi.
MaximumDynamicDisplayLevels Xác định số cấp menu được phép.
DataSourceID ID của SiteMapDataSource control dùng để cung cấp dữ liệu cho Menu lấy từ Web.sitemap.
Orientation Xác định menu ngang hay menu dọc.
RenderingMode Xác định cách thể hiện của menu bằng bảng và inline CSS hay dùng danh sách không thứ tự và CSS.
IncludeStyleBlock Hiển thị menu và CSS.

Thực hành tạo Menu cơ bản

Phần thực hành này sẽ thêm Menu vào trong thẻ <nav> của trang master page và hướng theo chiều ngang. Vì hướng theo chiều ngang nên nó chỉ phù hợp cho MonoChrome theme.

  • Mở trang master (Frontend.master) ở chế độ Resource, tìm đến thẻ <nav> và xoá tất cả nội dung bên trong.
  • Trong thanh Toolbox tìm mục Navigation và tìm đến Menu kéo Menu thả vào giữa cặp thẻ <nav> và thiết lập thuộc tính CssClass đến MainMenu:

  • Chuyển qua chế độ Design, giao diện sẽ trông như sau:

  • Khi đưa con trỏ chuột vào các Root sẽ xuất hiện mũi tên màu xám bên phải. Nhấp chuột vào đó để mở thanh Smart Task của Menu:

  • Chọn <New data source> từ mục Choose Data Source và chọn biểu tượng SiteMap từ hộp thoại Data Source Configuration Wizard hiện ra sau đó và OK:

  • Khi trở lại trang thì Menu control lúc này sẽ xuất hiện menu Home như sau:

  • Xem lại tập tin Web.sitemap chúng ta thấy rằng chúng ta sẽ có một menu duy nhất là Home. Trong Home có các menu con là Home, Reviews, About, Login. Trong menu Reviews có hai menu con là By GenreAll Reviews, trong About có hai menu con là Contact UsAbout Us:

  • Để hiển thị các con của Home, chúng ta nhấp chuột phảivào mục SiteMapDataSource dưới menu Home và chọn Properties:

  • Trong hộp thoại Properties chọn thuộc tính ShowStartingNode và chuyển giá trị của nó từ True sang False, các menu con trong Home sẽ hiện ra như sau:

  • Chọn Menu control và nhấp chuột phải chọn Properties, thay đổi các thuộc tính sau:

  • Xem mã Menu control trong chế độ Source:

  • Lưu tất cả. Chọn một trang nào đó, như Content.aspxCtrl + F5 và lưu ý rằng chúng ta chọn theme MonoChrome:

  • Các menu con trong Reviews hay About sẽ xuất hiện khi chúng ta lướt con trỏ chuột qua chúng (hover).
  • Các menu trên chưa được định dạng đáng kể; để làm điều này chúng ta sẽ tìm đến file CSS của theme MonochromeMonochrome.css và thêm các luật CSS vào file này. Mặc định, Menu control sẽ được chuyển thành các thẻ ul, li khi đến trình duyệt web và các cấp menu sẽ được gán cho các lớp CSS khác nhau như level1, level2,…  Do đó, các luật CSS được thêm vào Monochrome.css như sau:

.MainMenu ul.level1

{

/* Định dạng các menu cấp 1 như Home, Reviews, About, Login */

font-size: 14px;

font-weight: bold;

height: 19px;

line-height: 19px;

}

.MainMenu ul.level1 .selected

{

/* Khi các menu cấp 1 kích hoạt (hay chế độ active) */

background-color: #509EE7;

}

.MainMenu a.level1

{

/* Thêm các khoảng trống bên trái các mục menu*/

padding-left: 5px !important;

}

.MainMenu a.level2

{

/* Định dạng cho các menu cấp 2 như By Genre, All Reviews,... */

background-color: #555555;

padding-left: 8px;

}

.MainMenu a.level1:hover, a.level2:hover

{

/* Màu nền của các menu (cấp 1 và 2) khi hover */

background-color: #509EE7;

}

  • Chọn trang Content.aspxCtrl + F5:

  • Nhấp chuột phải vào trình duyệt (Chrome) và chọn View page source để xem nội dung HTML của Menu control:

Ở đây chúng ta dùng menu theo chiều ngang nên phù hợp với theme Monochrome, với theme DarkGrey sẽ phù hợp với menu dọc nhưng với dạng menu dọc, thay vì dùng Menu control, chúng ta sẽ dùng TreeView control.

Sử dụng TreeView control

TreeView thể hiện các mục (items) theo dạng cấu trúc cây giống cách thể hiện các thư mục, tập tin trong cửa sổ Windows Explorer. TreeView không lệ thuộc hẳn vào file Web.sitemap, nó có thể kết hợp với một file XML bất kì và tạo ra ra cây đề mục thông qua lập trình. Một số thuộc tính quan trọng của TreeView control:

Thuộc tính Mô tả
CssClass Cho phép dùng các class CSS.
CollapseImageUrl Hình ảnh thu gọn lại một phần cây khi nhấp chuột. Mặc định là dấu .
ExpandImageUrl Hình ảnh mở rộng một phần cây khi nhấp chuột. Mặc định là dấu +.
CollapseImageToolTip ToolTip được hiển thị khi người dùng lướ chuột qua một mục menu có thể thu gọn.
ExpandImageToolTip ToolTip được hiển thị khi người dùng lướt chuột qua một mục menu có thể mở rộng.
ShowExpandCollapse Quyết định liệu các mục trong TreeView có thể được thu gọn và mở rộng bằng cách nhấp một hình ảnh trước chúng.
ShowLines Xác định các hàng có thể được dùng để kết nối đến các mục nào đó trong TreeView.
ExpandDepth Xác định mức mở rộng của TreeView khi trang được tải lần đầu tiên. Mặc định là chế độ FullExpand, nghĩa là tất cả các mục trong TreeView đều hiển thị.

Thực hành dùng TreeView

Trong bài thực hành này chúng ta sẽ thêm TreeView vào <nav>, dưới Menu control. TreeView control sẽ dùng chung data source với Menu. Chúng ta cũng lập trình cho MenuTreeView xuất hiện tuỳ theo theme (MonochromeMenu, DarkGreyTreeView).

  • Mở trang master Frontend.master ở chế độ Resource, kéo TreeView control từ thanh Toolbox trong mục Navigation và thả vào trong phần tử <nav> dưới Menu control:

  • Thêm phần tử LevelStyles vào giữa cặp thẻ mở và đóng của TreeView như sau:

  • Các mục (ở mức 1) trong TreeView sẽ được định dạng bởi lớp CSS FirstLevelMenuItems được định nghĩa trong file DarkGrey.css của theme DarkGrey.
  • Chuyển trang master sang chế độ Design, nhấp chuột vào mũi tên bên phải của TreeView để mở thanh Smart Tasks. Từ Choose Data Source chọn SiteMapDataSource1, là data source được tạo cho Menu control:

  • Lúc này các mục trong TreeView sẽ hiển thị tất cả và ở chế độ có thể thu gọn (collapse) hay mở rộng (expand). Muốn TreeView chế độ bình thường, chúng ta chọn TreeView và nhấp chuột phải chọn Properties, chọn thuộc tính ShowExpandCollapse và chuyển giá trị của nó đến False, kết quả (để ý không còn biểu tượng dấu – ở trước các mục Reviews hay About):

  • Nhấp đôi chuột vào một vị trí bất kì để đến chế độ soạn code VB hay chúng ta có thể chọn file Frontend.master.vb. Trong chế độ soạn mã, trong sự kiện Page_Load thêm đoạn mã sau vào dưới dòng lệnh End If cuối cùng và ngay trên End Sub:

  • Đoạn mã trên thể hiện rằng, khi ta chọn theme DarkGrey thì Menu control sẽ ẩn và TreeView sẽ hiển thị và ngược lại khi chọn theme Monochrome.
  • Lưu tất cả và chọn lại trang Content.aspx, Ctrl+F5 và thử thay đổi các theme:

Để thuận tiện cho những bài sau chúng ta sẽ tạo các thư mục và các trang ASPX tương ứng như sau (và lưu ý rằng những trang ASPX sẽ chọn template là MyBasePage):

(Ví dụ tạo thư mục About, trong thư mục chứa 3 trang là Default.aspx, Contact.aspxAboutUs.aspx. Để tạo trang Default.aspx, chúng ta nhấp chuột phải thư mục About chọn Add > Add New Item, chọn MyBasePageFilenameDefault.aspx. Mở trang Default.aspx ở chế độ Resource và trong thẻ <Page> tim đến thuộc tính Title và thiết lập giá trị là About this Site).

Sử dụng SiteMapPath control

SiteMapPath control thể hiện vị trí hiện tại của bạn trong cấu trúc website, đó là một chuỗi các liên kết (hay còn gọi là breadcrumb). Giống như MenuTreeView, SiteMapPath cũng có nhiều thuộc tính kèm theo. Sau đây là một số thuộc tính phổ biến nhất:

Thuộc tính Mô tả
PathDirection Gồm hai giá trị là RootToCurrentCurrentToRoot. Giá trị RootToCurrent thể hiện chuỗi liên kết bắt đầu bằng vị trí gốc bên trái nhất và kết thúc là trang hay vị trí hiện tại bên phải. Giá trị CurrentToRoot ngược lại, bắt đầu là vị trí hiện tại bên trái nhất và kết thúc là vị trí gốc trong chuỗi liên kết.
PathSeparator Định nghĩa kí hiệu hay text hiển thị giữa các mục trong chuỗi liên kết. Mặc định là kí hiệu “>”.
RenderCurrentNodeAsLink Xác định mục cuối cùng trong chuỗi liên kết tức là vị trí hiện tại là một liên kết hay một văn bản thông thường. Mặc định giá trị là False tức là hiển thị dạng văn bản thông thường.
ShowToolTips Cho phép hiển thị tooltip khi người dùng hover qua các mục trong chuỗi liên kết.

Định dạng SiteMapPath control thực chất là định dạng các phần tử <a>SiteMapPath control khi đến trình duyệt web chỉ là thẻ <a> và text.

Thực hành sử dụng SiteMapPath

  • Mở trang master Frontend.master, thêm SiteMapPath control từ Toolbox mục Navigation vào vị trí <section> có IDMainContent và trên <asp: ContentPlaceHolder>, lưu ý có thêm hai thẻ <br>:

  • Lưu tất cả, chọn trang Content.aspx và Ctrl + F5:

  • Lúc này chúng ta vẫn chưa thấy SiteMapPath hiển thị, chọn một mục menu nào đó, ví dụ chọn Reviews và chọn By Genre, kết quả:

  • Nhấp vào Reviews trong chuỗi Home > Reviews > By Genre, kết quả:

  • Chuyển qua theme DarkGrey:

Lập trình chuyển trang

Chuyển trang là một trong những tính năng quan trọng, ví dụ trong bài thực hành thực hiện các phép toán ở chương trước, khi nhấn nút Calculate thì kết quả thay vì được hiển thị trên cùng trang, sẽ hiển thị sang một trang khác. Trong ASP.NET có ba cách thực hiện chuyển trang là dùng các lệnh Response.Redirect, Response.RedirectPermanentServer.Transfer. Hai lệnh đầu khác nhau ở tối ưu tìm kiếm, nếu Response.Redirect thông báo trang được chuyển tới chỉ là tạm thời (và còn có thể trở lại trang cũ) thì Response.RedirectPermanent thông báo trang chuyển tới là mãi mãi (và không trở lại trang cũ). Các phương thức RedirectRedirectPermanent có thể được định nghĩa lại theo nhu cầu người dùng (overload).

Thông thường khi chúng ta chuyển người dùng đến một trang khác, chúng ta thường muốn kèm theo một số thông tin. Chúng ta có thể làm điều này bằng chuỗi truy vấn (query string), phần kèm theo url và sau dấu ?. Ví dụ chuỗi in đậm sau là một query string:


http://localhost:49246/Demos/Target.aspx?CategoryId=10&From=Home

Trong chuỗi trên gồm hai cặp thuộc tính – giá trị là CategoryId – 10From – Home; các cặp này cách nhau bởi dấu &. Trang Target.aspx đọc chuỗi truy vấn bằng phương thức Request.QueryString.

Thực hành chuyển người dùng đến trang khác

Trong bài thực hành này chúng ta sẽ dùng phương thức Response.Redirect để chuyển người dùng đến trang khác.

  • Trong thư mục Demos, tạo hai trang Source.aspxTarget.aspx với template là MyBasePage, giá trị thuộc tính Title tương ứng là SourceTarget.
  • Mở trang Source.aspx  ở chế độ Design và nhấp đôi chuột tại một vị trí bất kì trong vùng màu xám (vùng chỉ đọc) để đến cửa sổ soạn mã VB và đến trình xử lí sự kiện Page_Load và thêm dòng code như sau:

  • Mở trang Target.aspx ở chế độ Design, thêm một Label vào vùng cpMainContent:

  • Đến trình sự kiện Page_Load và thêm dòng mã sau:

  • Lưu tất cả, chọn trang Source.aspxCtrl + F5, thay vì hiển thị trang Source.aspx, người dùng sẽ được chuyển đến trang Target.aspx cùng với nội dung trong query string hiển thị trên Label:

Trái ngược với hai phương thức RedirectRedirectPermanent chuyển người dùng đến trang khác tại máy khách (client), phương thức Server.Transfer chuyển người dùng đến trang khác tại Server. Đối với hai phương thức RedirectRedirectPermanent,  chuỗi truy vấn hiển thị trước người dùng và có thể bị sửa đổi gây nên những vấn đề về bảo mật, với phương thức Transfer tên trang và chuỗi truy vấn sẽ được ẩn đi và phương thức này cũng làm tốc độ chuyển trang nhanh hơn vì nó chuyển người dùng đến trực tiếp trang mới. Tuy nhiên, phương thức Transfer chỉ dùng khi cần chuyển đến các trang trong cùng một website, nếu chuyển đến trang thuộc miền khác thì ASP.NET sẽ báo lỗi.

Thực hành dùng phương thức Transfer

  • Mở lại trang mã VB của trang Source.aspx (tập tin Source.aspx.vb), đến Page_Load và che dòng code trước đó (dùng phương thức Redirect) thay bằng dòng mã mới (dùng phương thức Transfer):

  • Lưu, chọn lại trang Source.aspxCtrl + F5, để ý thanh địa chỉ và so sánh với url khi dùng phương Redirect ở trên: