C# cơ bản .NET Core

Dẫn nhập về Layout trong ASP.NET Core

Trong phần này tìm hiểu về tổ chức tạo bố cục chung cho các trang Razor Page trong ASP.NET Core. Trong ứng dụng Web thường là có nhiều trang, mà các trang này có thể có những thành phần giống nhau trên trang, như giống nhau phần header, footer, menu điều hướng ... Do vậy, để tránh mỗi trang lại phải tạo những thành phần này lại cho trang đó thì cần có cơ chế tạo một bố cục chung, các trang chia sẻ cùng bố cục. Đó là Layout trong ASP.NET Core.

Hay nhanh chóng tạo ra một dự án ASP.NET Core Razor Pages để thực hảnh, tạo thư mục razor02.layout, vào và gõ lệnh

dotnet new webapp

Nhìn vào cấu trúc thư mục bố trí các file .cshtml (Razor Page) trong thư mục Pages, thấy có các file mà tên bắt đầu bằng _ đó là các file được phối hợp để tạo ra layout (bố cục) của các trang. Các file đó như:

  • _ViewStart.cshtml
  • _ViewImports.cshtml
  • Shared/_Layout.cshtml
  • Shared/_ValidationScriptsPartial.cshtml

Ví trí các file này nên thực hành bố trí các file này như vậy, kể cả khi đổi thư mục gốc chứa các Razor Page ( Đổi thư mục Razor Page )

razor02

Trang bố cục chính _Layout.cshtml

File Shared/_Layout.cshtml là bố cục chính (master) sử dụng bởi các trang. Mở file này ra nó có cấu trúc như sau:

Lúc này các trang Razor Page nào chỉ định sử dụng Layout này thì nội dung của do Razor Page đó sinh ra được chèn vào ví trí:

@RenderBody()

Ngoài ra nó cũng chèn section có tên Script, nếu trang Razor sử dụng layout có định nghĩa Section này (Xem chỉ thị @section ở Cú pháp Razor), ví trí chèn ở dòng

@RenderSection("Scripts", required: false)

Dữ liệu truyền từ Razor Page sang Layout có thể sử dụng đối tượng lớp ViewDataDictionary có tên ViewData, trường hợp trên là lấy tiêu đề chèn vào layout ở dòng

<title>@ViewData["Title"] - razor02.layout</title>

Cấu hình Razor Page sử dụng _Layout.cshtml

Khi đã có file layout chính Shared/_layout.cshtml làm sao để một Razor Page biết là cần phải sử dụng Layout này? Đơn giản, tại Razor Page thiết lập cho nó thuộc tính Layout bằng tên layout muốn sử dụng (tên không cần .cshtml), ví dụ:

@{
    Layout = "_Layout";
}

Nếu bạn có một layout khác, ví dụ Shared/Theme/MyTheme/_MyLayout.cshtml (nhớ layout phải có dòng @RenderBody() để biết chèn vào đâu) thì bạn khai báo trong Razor Page

@{
    Layout = "Theme/MyTheme/_MyLayout";
}

Nếu muốn hủy sử dụng layout của một trang Razor thì gán Layout = null; ở cấu trúc trên

File _ViewStart.cshtml

Trong cấu trúc thư mục Razor Page thấy có file _ViewStart.cshtml,nếu có file này thì ASP.NET Core Razor cấu hình được tự động chèn nội dung viết trong nó vào các file Razor Page.

Ví dụ, thay vì mỗi trang Razor cần thiết lập layout sử dụng là _Layout.cshtml thì bạn viết cấu hình này trong file _ViewStart.cshtml

@{
    Layout = "_Layout";
}

Từ đây trở đi, các Razor Page được tự động chèn nội dung trên mỗi khi nó được gọi.

Layout lồng nhau

Bạn có thể tạo layout con nằm trong layout khác, hãy thực hành một trường hợp như sau:

Tạo ra một Layout gọi đặt tên là MaterLayout trong thư mục /Shared/Product/_MaterLayout.cshtml có nội dúng

<!DOCTYPE html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>@ViewData["title"]</title>
  <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
  <link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
    <div class="bg-danger p-4">Header của trang</div>
    @RenderBody()
    <div class="bg-success p-4">Footer của trang</div>
</body>
</html>

Bạn đã có thể sử dụng ngay Layout bởi Razor Page này như trên. Tuy nhiên nếu muốn nội dung Razor Page sinh ra, chèn vào một layout khác rồi kết quả mới được chèn vào MasterLayout, nghĩa là một layout lồng vào layout khác. Ta tạo ra một layout con giả sử đặt tên là SubLayout /Shared/Product/_SubLayout.cshtml, có nội dung:

@{
   Layout = "Theme/Product/_MasterLayout";
}

<h2>Thông tin sản phẩm</h2>
<div class="card bg-warning m-4">
    @if (@ViewData["TenSanPham"] != null) {
        <h3 class="card-header">@ViewData["TenSanPham"]</h3>
    }
    <div class="card-body">
       @RenderBody()
    </div>
</div>

Bạn thấy SubLayout thiết lập Layout của nó là MasterLayout, nghĩa là nội dung của SubLayout được chèn vào MasterLayout ở @RenderBody

Lúc này, ở trang Razor nào đó sử dụng Layout là SubLayout thì nội dung trang Razor chèn vào SubLayout kết quả mang chèn vào MasterLayout và có được HTML cuối dùng, ví dụ: ViewProduct.cshtml

@page

@{
   Layout = "Theme/Product/_SubLayout";
   var product = new {
     name = "Iphone",
     des = "Điện thoại Iphone jfldsj fdskljfdskfd",
     price = "100"
   };


   ViewData["title"] = "Xem sản phẩm " + product.name;
}

<h3>@product.name</h3>
<div>@product.des</div>
<div>Giá: @product.price</div>
razor02

File _ViewImports.cshtml

Trong thư mục Pages bạn thấy có file _ViewImports.cshtml, file này cung cấp cơ chế để thêm các chỉ thị toàn cục, nó tự động thêm các chỉ thị vào các Razor Page mà bạn không phải khai báo trong từng file Razor Page cụ thể.

File này hỗ trợ các chỉ thị gồm:

@addTagHelper
@inherits
@namespace
@inject
@model
@removeTagHelper
@tagHelperPrefix
@using

Trong ví dụ này, file có nội dung như sau

@using razor02.layout
@namespace razor02.layout.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Nội dung này tự động chèn vào các file .cshtml khi được triệu gọi.

chỉ thị @using, @namespace xem ý nghĩa của nó ở phần trước. Chỉ thị @addTagHelper thêm các Tag Helper hỗ trợ trong Razor, cú pháp giúp sinh các mã các phần tử HTML, nói ở những bài tiếp theo

Tham khảo mã nguồn ASP_NET_CORE/razor02.layout hoặc tải về ex056


Đăng ký nhận bài viết mới