ASP.NET MVC 5: Thêm View


Trong phần này chúng ta sẽ sửa lại lớp HelloWorldController class để dùng các file template cho view nhằm giúp việc tạo phản hồi dạng HTML về cho trình duyệt dễ dàng hơn.

Bạn sẽ tạo một file template sử dụng Razor view engine. Các file view dựa trên Razorcó phần mở rộng .cshtml, và cung cấp một các rõ ràng để tạo ra nội dung HTML sử dụng C#. Razor tối thiểu hóa số ký tự và số lần gõ phím để viết một template, và cho phép việc code nhanh chóng và trôi chảy hơn.

Hiện tại phương thức Index trả về một chuỗi với một thông điệp được hard-coded trong lớp controller. Sửa lại phương thức Index để trả về một đối tượng View, như hình dưới đây:

public ActionResult Index() 
{ 
    return View(); 
}

Phương thức Index ở trên dùng một view template để tạo ra nội dung HTML trả về trình duyệt. Các phương thức của controller (còn gọi là các phương thức action – action method), kiểu như Index ở trên, thông thường sẽ trả về một đối tượng ActionResult, hoặc một lớp thừa kế từ ActionResult, chứ không phải một kiểu nguyên thủy như string.

Đầu tiên, hãy tạo một thư mục view cho controller HelloWorld. Nhấn nút phải chuột vào view, sau đó click Add, và tiếp tục nhấn vào New Folder.

Đặt tên thư mục là HelloWorld.

Nhấn phải lên thư mục HelloWorld và nhấn Add, sau đó nhấn Scaffold.

Trong hộp thoại Add Scaffold, nhấn MVC 5 View – Empty without model. Tiếp tục nhấn Add.

Trong hộp thoại Add View, đặt tên view là Index, giữ nguyên các giá trị khác và nhấn Add.

File MvcMovie\Views\HelloWorld\Index.cshtml đã được tạo.

Hình sau cho thấy file Index.cshtml đã được tạo:

HelloWorldIndex

Thêm chuỗi HTML sau vào dưới thẻ <h2>.

<p>Hello from our View Template!</p>

Toàn bộ file MvcMovie\Views\HelloWorld\Index.cshtml giờ sẽ giống như dưới đây.

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>Hello from our View Template!</p>

Nhấn nút phải vào Index.cshtml file và chọn View in Page Inspector.

PI

Xem phần Page Inspector tutorial để có thêm thông tin.

Một cách khác là bạn có thể chạy ứng dụng và duyệt đến HelloWorld controller (http://localhost:xxxx/HelloWorld). Phương thức Index trong controller này hiện không làm gì nhiều; nó đơn giản gọi câu lệnh return View(), có nghĩa là nó muốn dùng một file template để tạo phản hồi cho người dùng. Vì ta đã không chỉ ra tên file, do vậy ASP.NET MVC sẽ mặc nhiên lấy tên là Index.cshtml trong thư mục Views\HelloWorld. Hình dưới đây hiển thị chuỗi “Hello from our View Template!” viết trong file view.

Giờ trông đã rất tốt rồi. Tuy nhiên để ý bạn sẽ thấy trên thanh tiêu đề trình duyệt hiện ra “Index My ASP.NET Appli” và liên kết lớn trên đầu trang là “Application name.” Nếu thu nhỏ cửa sổ trình duyệt lại, bạn có thể  phải nhấn lên nút với ba gạch ngang ở góc trên phải để thấy được các liên kết HomeAboutContactRegister và Log.

Thay đổi View và cách hiển thị trang

Trước tiên, bạn muốn thay đổi liên kết “Application name” trên đầu trang. Đoạn văn bản này sẽ được hiển thị trên đầu tất cả các trang. Nó thực ra chỉ được viết ở một nơi trong toàn bộ project, mặc dù sẽ xuất hiện trên mọi trang. Chuyển đến thư mục /View/Shared trong Solution Explorer và mở file _Layout.cshtml, file này còn được gọi là trang layout và nó được chia sẻ cho tất cả các trang khác dùng.

_LayoutCshtml

Layout template cho phép bạn chỉ ra cách hiển thị cho bộ khung HTML tại một nơi và sau đó áp dụng cho toàn bộ site. Tìm dòng @RenderBody, đây là mục đánh dấu nơi tất cả các trang bạn sẽ hiển thị, và nội dung đó sẽ được “đóng khung” bên trong layout template. Ví dụ, nếu bạn chọn liên kết About, view Views\Home\About.cshtml sẽ được hiển thị bên trong phương thức RenderBody.

Sửa lại ActionLink trong layout template từ “Application name” thành “MVC Movie”.

<body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="navbar-inner">
            <div class="container">
                <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                @Html.ActionLink("MVC Movie", "Index", "Home", null, new { @class = "brand" })
                <div class="nav-collapse collapse">
                    <ul class="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>

Thay thế nội dung phần tiêu đề với đoạn thẻ sau:

<!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>

Chạy lại ứng dụng, bạn sẽ thấy nó hiển thị “MVC Movie”. Nhấn vào liên kết About, và bạn thấy nó cũng vẫn hiển thị “MVC Movie”. Vậy là chúng ta đã có thể thay đổi ở một nơi và ánh xạ thay đổi đó lên tất cả các trang trong site.

Giờ ta sẽ thay đổi tiếp tiêu đề của trang Index.

Mở MvcMovie\Views\HelloWorld\Index.cshtml. Có hai chỗ cần sửa: thứ nhất là đoạn văn bản xuất hiện trên tiêu đề trình duyệt, và thứ hai là là phần header thứ hai (đoạn bên trong thẻ <h2>). Bạn sẽ làm cho chúng khác đi một chút để có thể thấy được đoạn code nào đã thay đổi phần nào trong ứng dụng.

@{
    ViewBag.Title = "Movie List";
}

<h2>My Movie List</h2>

<p>Hello from our View Template!</p>

Để chỉ ra tiêu đề HTML, đoạn code ở trên đặt thuộc tính Title của đối tượng ViewBag (bên trong file Index.cshtml). Chú ý là phần layout mẫu ( Views\Shared\_Layout.cshtml ) dùng giá trị này trong thẻ <title> như một phần trong hoạn <head> mà ta đã thay đổi trước đó.

<!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>

Nhờ sử dụng ViewBag, bạn có thể dễ dang truyền các tham số giữa view và layout.

Chạy ứng dụng và mở trang http://localhost:xx/HelloWorld. Chú ý phần tiêu đề, phần đầu trang chính (<h1>) và phần đầu trang phụ (<h2>) đã thay đổi. (Nếu bạn không thấy thay đổi, có thể bạn đang xem phiên bản bị cache. Nhấn Ctrl-F5 trong trình duyệt để yêu cầu tải lại nội dung trang từ server). Tiều để trình duyệt được tạo với ViewBag.Title ta đặt trong Index.cshtml và phần “- Movie App” được thêm vào trong file layout.

Bạn cũng đã thấy cách file Index.cshtml được trộn với _Layout.cshtml để tạo nên một nội dung HTML duy nhất để trả về cho trình duyệt. Các layout template làm cho việc thay đổi xuyên suốt toàn bộ site trở nên thực sự dễ dàng.

Đoạn dữ liệu nhỏ của chúng ta (trong trường hợp này là chuỗi “Hello from our View Template!”) hiện vẫn được hard-coded. Ứng dụng MVC giờ đã có “V” (view) ,”C” (controller), nhưng vẫn chưa có “M” (model). Chúng ta sẽ sớm tìm hiểu các bước để tạo một cơ sở dữ liệu (CSDL) và lấy các model từ đó.

Chuyển dữ liệu từ Controller sang View

Trước khi chúng ta đến phần CSDL và nói về model, chúng ta hãy nói một chút về ách truyền thông tin dừ controller sang view. Các lớp controller được gọi để phản hồi các request. Một lớp controller là nơi bạn viết code để xử lý các yêu cầu, lấy dữ liệu từ database, và quyết định kiểu phản hồi sẽ trả về lại cho trình duyệt. Các view template có thể được dùng từ controller để tạo và định dạng nội dung phản hồi về cho trình duyệt.

Các controller có nhiệm vụ cung cấp bất kỳ dữ liệu hoặc đối tượng nào để một view template dựa trên đó tạo nên phản hồi. Một quy tắc quan trọng: Không nên thực hiện các xử lý logic hay tương tác với một CSDL một cách trực tiếp. Thay vào đó, một view template chỉ làm việc với dữ liệu mà nó được cung cấp bởi controller. Việc đảm bảo quy tắc “separation of concerns” này sẽ giúp code của bạn sạch, dễ kiểm lỗi và bảo trì dễ dàng hơn.

Hiện tại, phương thức action Welcome trong lớp HelloWorldController nhận vào hai tham số namenumTimes, sau đó trả giá trị trực tiếp về trình duyệt. Thay vì để controller tạo nên phản hồi như một string, ta sẽ sửa lại controller để dùng một view template. View template sẽ tạo một phản hồi động, có nghĩa là bạn sẽ cần truyền các phần dữ liệu cần thiết từ controller sang view để có thể tạo được response. Bạn có thể làm điều này bằng cách yêu cầu controller đưa các dữ liệu động cần cho view template thông qua đối tượng ViewBag.

Quay lại file HelloWorldController.cs và sửa lại phương thức Welcome để thêm vào giá trị cho 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ể đưa bất thứ gì bạn muốn vào cho nó; đối tượng ViewBag không có bất kỳ thuộc tính nào được định nghĩa cho đến khi bạn đưa giá trị cho nó. Hệ thống model binding của ASP.NET MVC sẽ ánh xạ các tham số theo tên và đưa các giá trị từ query string vào các tham số trong phương thức của bạn. File HelloWorldController.cs hoàn chỉnh sẽ trông như nhau:

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();
        }
    }
}

Giờ ViewBag chứa dữ liệu mà nó sẽ được truyền vào một cách tự động.

Tiếp đến, bạn cần một view template cho trang Welcome. Trong menu Build, chọn Build Solution (hoặc nhấn Ctrl-Shift-B) để đảm bảo project đã được dịch.

Nhấn phải chuột vào folder Views\HelloWorld và nhấn Add, sau đó nhấn Scaffold.

Trong hộp thoại Add Scaffold, nhấn MVC 5 View – Empty without model.

Trong hộp thoại Add View, đặt tên cho view là Welcome.

Giờ file MvcMovie\Views\HelloWorld\Welcome.cshtml file đã được tạo.

Thêm đoạn code sau vào phía dưới thẻ <h2> trong file Welcome.cshtml. Bạn sẽ tạo một vòng lặp “Hello” theo số lượng người dùng yêu cầu. File Welcome.cshtml được hiển thị dưới đây.

@{
    ViewBag.Title = "Welcome";
}

<h2>Welcome</h2>

<ul>
    @for (int i = 0; i < ViewBag.NumTimes; i++)
    {
        <li>@ViewBag.Message</li>
    }
</ul>

Chạy chương trình và mở địa chỉ sau:

http://localhost:xx/HelloWorld/Welcome?name=Scott&numtimes=4

Giờ dữ liệu được truyền lên URL và được chuyển tới controller nhờ model binder. Controller sau đó sẽ đóng gói dữ liệu vào đối tượng ViewBag và tiếp tục truyền đến view. View sau đó sẽ hiển thị dữ liệu này cho người dùng dưới dạng HTML.

Trong đoạn ví dụ mẫu ở trên, ta đã dùng ViewBag để truyền dữ liệu từ controller sang view. Trong các phần sau của loạt bài này, ta sẽ dùng view model để chuyển dữ liệu từ controller sang view. Cách tiếp cận view model để chuyển dữ liệu nên được dùng hơn là sử dụng ViewBag. Xem thêm Dynamic V Strongly Typed Views để có thêm thông tin.

Vậy là ta đã có thêm phần “M” của model, nhưng hiện vẫn chưa sử dụng đến CSDL. Phần tiếp theo ta sẽ sử dụng những gì đã học và tạo một cơ sở dữ liệu phim ảnh.

One thought on “ASP.NET MVC 5: Thêm View

Gửi phản hồi

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s