Trong phần này, bạn sẽ sửa đổi file “HelloWorldController.cs”, sử dụng view để đóng gói quá trình sinh ra HTML trả về cho client.
Bạn sẽ tạo một view sử dụng “Razor view engine”. “Razor view” có phần mở rộng là “.cshtml” và cung cấp cách thức để tạo ra HTML sử dụng C#. Razor sẽ giúp tinh gọn mã lệnh khi bạn viết một view.
Hiện tại, phương thức “Index” trả về một chuỗi là một thông báo đã được khai báo trong Controller. Chúng ta sẽ thay đổi phương thức “Index” để trả về một đối tượng view:
[sourcecode language=”csharp”]
public ActionResult Index()
{
return View();
}
[/sourcecode]
Phương thức “Index” ở trên sử dụng một view để sinh ra HTML trả về cho trình duyệt. Các phương thức trong Controller (gọi là action methods) như phương thức “Index” ở trên thường trả về ActionResult (hoặc một lớp dẫn xuất từ ActionResult), không phải các kiểu nguyên thủy như string.
Chuột phải vào thư mục “Views\HelloWorld” và nhấn “Add”. Sau đó chọn “MVC 5 View Page with Layout (Razor)”:
Trong hộp thoại “Specify Name for Item”, nhập vào “Index” sau đó nhấn “OK”:
Trong hộp thoại “Select a Layout Page”, chọn “_Layout.cshtml” và nhấn “OK”:
Trong hộp thoại ở trên, thư mục “Views\Shared” được chọn ở danh mục bên trái. Và như vây, file “MvcMovie\Views\HelloWorld\Index.cshtml” đã được tạo:
Trong file “Index.cshtml” bạn thêm vào như sau:
[sourcecode language=”html”]
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>Hello from our View Template!</p>
[/sourcecode]
Chuột phải vào file “Index.cshtml” và chọn “View in Browser”:
Hoặc bạn cũng có thể chạy ứng dụng và duyệt đến “http://localhost:xxxx/HelloWorld”. Phương thức “Index” trong Controller của bạn sẽ chạy câu lệnh “return View()”. Bởi vì bạn không xác định chính xác tên view được sử dụng. ASP.NET MVC mặc định sử dụng file “Index.cshtml” trong thư mục “\Views\HelloWorld”. Kết quả khi chạy như sau:
Thay đổi các views và các trang layouts
Trước tiên, chúng ta sẽ thay đổi liên kết “Application name” ở đầu trang. Đây là thành phần chung của tất cả các trang. Nó được viết tại một chỗ trong dự án nhưng sẽ xuất hiện trên mọi trang trong ứng dụng. Bạn mở file _Layout.cshtml trong thư mục “/Views/Shared”. File này được gọi là trang bố cục và nó nằm trong thư mục “Shared” để tất cả các trang khác có thể sử dụng.
Layout cho phép bạn xây dựng mã HTML ở một nơi và sau đó áp dụng nó ở nhiều nơi khác trong trang WEB của bạn. Trong trang layout, “@RenderBody()” sẽ là nơi giữ chỗ, là vị trí mà bạn sẽ gắn trang con vào trang layout. Ví dụ: nếu bạn chọn trang “About”, trang “Views\Home\About.cshtml” sẽ được thi hành bên trong phương thức “RenderBody”.
Thay đổi nội dung của phần tử “Title”. Thay đổi “ActionLink” trong file layout từ “Application name” thành “MVC Movie” và controller từ “Home” thành “Movies”. File layout sau khi thay đổi sẽ như sau:
[sourcecode language=”html”]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title – Movie App</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@Html.ActionLink("MVC Movie", "Index", "Movies", null, new { @class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
@Html.Partial("_LoginPartial")
</div>
</div>
</div>
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>© @DateTime.Now.Year – My ASP.NET Application</p>
</footer>
</div>
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", required: false)
</body>
</html>
[/sourcecode]
Chạy ứng dụng, và duyệt đến “http://localhost:xxxx/HelloWorld” .“Application name” đã chuyển thành “MVC Movie”:
Nhấn vào “About”, “Contact” bạn cũng sẽ thấy sự thay đổi tương tự. Điều này là bởi vì, trang “Index”, “About”, “Contact” sử dụng chung một layout.
Trong file “Views\HelloWorld\Index.cshtml” có chứa đoạn mã sau:
[sourcecode language=”html”]
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
[/sourcecode]
Đoạn mã này sử dụng để thiết lập layout “_Layout.cshtml” cho một trang. Nó cũng được khai báo trong “Views\_ViewStart.cshtml”. File “Views\_ViewStart.cshtml” định nghĩa layout chung mà tất cả các trang sẽ sử dụng. Do đó bạn không cần khai báo đoạn mã trên trong file “Views\HelloWorld\Index.cshtml” nữa. Bạn có thể sửa lại file “Views\HelloWorld\Index.cshtml” như sau:
[sourcecode language=”html”]
@*@{
Layout = "~/Views/Shared/_Layout.cshtml";
}*@
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>Hello from our View Template!</p>
[/sourcecode]
Bạn cũng có thể sử dụng thuộc tính “Layout” để thiết lập layout khác, hoặc thiết lập giá trị “null” nếu không có layout nào được sử dụng.
Bây giờ, chúng ta hãy thay đổi tiêu đề của trang “Index”. Bạn mở file “Views\HelloWorld\Index.cshtml”. Chúng ta sẽ thay đổi ở hai vị trí. Đầu tiên là văn bản xuất hiện trong tiêu đề của trình duyệt và sau đó là trong phần tử “h2”.
[sourcecode language=”html”]
@{
ViewBag.Title = "Movie List";
}
<h2>My Movie List</h2>
<p>Hello from our View Template!</p>
[/sourcecode]
Chúng ta sử dụng thuộc tính “Title” của đối tượng “ViewBag” để thiết lập giá trị cho tiêu đề. File “Views\Shared\_Layout.cshtml” sẽ sử dụng giá trị này trong phần tử “title”.
[sourcecode language=”html”]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title – Movie App</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
[/sourcecode]
Sử dụng “ViewBag”, bạn cũng có thể dễ dàng truyền các thông số khác giữa view và layout. Chạy ứng dụng và bạn sẽ nhận thấy sự thay đổi. Tiêu đề trình duyệt được tạo với ViewBag.Title chúng ta đặt trong file “Index.cshtml” và thêm “- Movie App” trong file “_Layout.cshtml”.
Chú ý rằng nội dung trong file “Index.cshtml” đã được sáp nhập với nội dung trong file “_Layout.cshtml” và trả về một HTML duy nhất để gửi tới trình duyệt. Layout giúp bạn có thể dễ dàng thực hiện những thay đổi áp dụng trên tất cả các trang của ứng dụng.
Truyền dữ liệu từ Controller tới View
Controller là nơi tiếp nhận và xử lý các yêu cầu từ trình duyệt. Controller lấy dữ liệu từ cơ sở dữ liệu và quyết định loại dữ liệu nào sẽ được trả về cho trình duyệt. Sau đó View được sử dụng để tạo ra HTML trả dữ liệu về cho trình duyệt.
Controller có trách nhiệm cung cấp bất cứ dữ liệu hoặc đối tượng nào được yêu cầu để View hiển thị ra trình duyệt. View không bao giờ thi hành các nghiệp vụ logic hoặc tương tác trực tiếp với cơ sở dữ liệu. Thay vào đó, View chỉ làm việc với dữ liệu được cung cấp bởi Controller. Điều này sẽ khiến cho mã của bạn sạch sẽ, dễ kiểm chứng và bảo trì.
Hiện tại, phương thức Welcome trong lớp HelloWorldController lấy tham số “name” và tham số “numTimes” truyền vào sau đó xuất các giá trị trực tiếp tới trình duyệt. Thay vì trả về một chuỗi như trên, chúng ta sẽ để Controller trả về một View. Bạn có thể sử dụng đối tượng ViewBag để lưu dữ liệu, và View sẽ truy cập đối tượng ViewBag để lấy dữ liệu trả về cho trình duyệt.
Trong file “HelloWorldController.cs”. Chúng ta sẽ đi thay đổi phương thức “Welcome”. Bạn thêm giá trị Message và NumTimes vào đối tượng ViewBag. ViewBag là một đối tượng động. Có nghĩa là bạn có thể gán bất cứ thứ gì cho nó. Đối tượng ViewBag không có thuộc tính được xác định cho đến khi bạn gán cái gì đó cho nó. ASP.NET MVC sẽ tự động ánh xạ các tham số (name và numTimes) từ chuỗi truy vấn trong thanh địa chỉ đến các tham số trong phương thức “Welcome”. File “HelloWorldController.cs” sau khi sửa đổi sẽ như sau:
[sourcecode language=”csharp”]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcMovie.Controllers
{
public class HelloWorldController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Welcome(string name, int numTimes = 1)
{
ViewBag.Message = "Hello " + name;
ViewBag.NumTimes = numTimes;
return View();
}
}
}
[/sourcecode]
Bây giờ đối tượng ViewBag chứa dữ liệu sẽ tự động truyền tới View. Tiếp theo bạn cần tạo View “Welcome”.
Chuột phải vào thư mục “Views\HelloWorld” và nhấn “Add”, sau đó chọn “MVC 5 View Page with Layout (Razor)” :
Trong hộp thoại “Specify Name for Item” nhập Welcome và nhấn OK:
Trong hộp thoại “Select a Layout Page”, chọn “Shared”, chọn “_Layout.cshtml” và nhấn OK:
File “MvcMovie\Views\HelloWorld\Welcome.cshtml” đã được tạo.
Trong file “Welcome.cshtml”, bạn tạo vòng lặp để hiển thị “name” với “numTimes” lần:
[sourcecode language=”html”]
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
@{
ViewBag.Title = "Welcome";
}
<h2>Welcome</h2>
<ul>
@for (int i = 0; i < ViewBag.NumTimes; i++)
{
<li>@ViewBag.Message</li>
}
</ul>
[/sourcecode]
Chạy ứng dụng và duyệt tới URL sau:
“http://localhost:xxxx/HelloWorld/Welcome?name=Scott&numtimes=4”
Bây giờ, dữ liệu sẽ được lấy từ URL và truyền vào Controller sử dụng model binder. Controller sẽ đóng gói dữ liệu vào đối tượng ViewBag và truyền ViewBag tới view. Sau đó view sẽ hiển thị dữ liệu dưới dạng HTML.
Trong ví dụ trên, chúng ta đã sử dụng đối tượng ViewBag để truyền dữ liệu từ controller tới view. Trong bài học tiếp theo, chúng ta sẽ sử dụng view model để truyền dữ liệu từ controller tới view.