Sử dụng Layouts và Section trong ASP.NET Core

Layouts và Section trong ASP.NET MVC Core giúp chúng ta đảm bảo sự thống nhất giữa các trang trong toàn bộ các view của ứng dụng. Trong bài này chúng ta sẽ tìm hiểu cách tạo trang Layout và chia sẻ nó cho các view. Chúng ta sẽ sử dụng phương thức RenderBody để tạo ra View. Chúng ta cũng được biết làm thế nào định nghĩa các section và sử dụng nó với RenderSection. Cuối cùng chúng ta sẽ tìm hiểu về _ViewStart trong việc định nghĩa Layout.

Layout của trang web

Thiết kế của hầu hết các website bao gồm một menu, một phần header, footer và phần thanh sidebar. Như bạn thấy đi từ một trang này đến trang kia trong website thì chỉ có nội dung ở giữa là thay đổi. Nhưng menu, header, footer hay màu sắc toàn cục vẫn giữ nguyên. Điều này giúp website có cái nhìn thống nhất. 

Một ứng dụng web nhìn cơ bản sẽ như sau:

 

Layout trong ASP.NET Core là gì?

Views trong ASP.NET Core được tạo ra từ file .cshtml được đặt trong thư mục Views. Để giữ cho việc đồng nhất giữa các trang, chúng ta cần thêm header, footer và thanh điều hướng ở tất cả các view. Tuy nhiên điều này thường vướng víu và dễ sai sót đặc biệt nếu ta có nhiều view. Trang layout trong ASP.NET Core giúp chúng ta định nghĩa một giao diện có các phần tử dùng chung như header, footer, navigation menu trên trang ở một vị trí mà có thể dùng cho mọi nơi.

Project ví dụ

Mở một ứng dụng ASP.NET Core, chúng ta sử dụng kiến thức ở bài Bắt đầu khởi tạo ứng dụng ASP.NET Core.

Vị trí của trang Layout

Theo quy ước của ASP.NET Core MVC thì các view được lưu trong thư mục Views. Mỗi Controller sẽ có một thư mục con trong thư mục Views tương ứng với tên trung với tên controller nhưng không có hậu tố "Controller". Tất cả các view được liên kết với controller trong thư mục này. Thư mục Views cũng có chứa thư mục tên là Shared, nơi chứa các view chia sẻ cho nhiều view khác dùng chung. Vì thế Layouts được đặt trong thư mục này: Views/Shared.

Làm sao để tạo Layout

Tạo một thư mục tên là Shared bên trong thư mục Views. Chuột phải vào thư mục Shared chọn Add View. Và đặt tên View là _Layout. Chọn Empty Template và không chọn vào cả 2 checkbox Create as a partial viewUse a layout page vì chính thằng này không phải partial view cũng không cần sử dụng một layout page nào vì nó là layout to nhất rồi. Trong tương lai vẫn có những layout là con của 1 layout khác chúng ta sẽ tìm hiểu sau.

 

Click vào Add để tạo View. Nó sẽ tạo ra file _Layout.cshtml trong thư mục Views/Shared. Mở nó ra và dán đoạn nội dung này vào.

<!DOCTYPE html>
 
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Layout Example</title>
</head>
<body>
    
    <div id="header">
        <h1>Layout example in HTML</h1>
    </div>
 
    <div id="content">
        @RenderBody()
    </div>
 
    <div id="Footer">
        <p>This is Footer</p>
    </div>
 
</body>
</html>

Đoạn HTML này có 3 phần là header, content và footer. Content là phần mà bạn muốn thêm nội dung các view khác vào.

RenderBody

RenderBody là một phương thức đặc biệt đánh dấu vị trí nơi mà các view sử dụng Layout này sẽ được đặt vào đó khi chạy. Cơ bản thì nó là một vùng định trước của các View sẽ hiển thị ở đó.

@RenderBody()

Chỉ có một RenderBody được gọi trong một trang Layout.

Chỉ ra Layout được sử dụng trong View

Thay đổi nội dung Index Action method trong HomeController như sau:

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

Mở Index.cshtml ra từ Views/Home và copy dòng:

@{
    Layout = "_Layout";
}
 
<p>Here goes the content</p>

Index view trở nên đơn giản hơn. Chúng ta sẽ loại bỏ các thẻ <html>, <head> và <body> . Các thẻ này giờ đây chuyển sang trang layout. Dòng đầu tiên của code là khối Razor, chúng ta định nghĩa trang layout sẽ được dùng cho view này. Chạy ứng dụng và nhìn kết quả.

Giờ hãy thêm một Action method khác tên AboutUs trong HomeController.

public IActionResult AboutUs()
{
    return View();
}

Giờ hãy thêm một View và chọn Layout:

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}
 
<h2>About Us</h2>

Giờ hãy chạy ứng dụng và vào URL: /Home/AboutUs. Bạn sẽ thấy nội dung đã thay đổi khi header và footer đã được thêm vào từ Layout

 

Đường dẫn Layout

Chúng ta sử dụng đường dẫn đầy đủ "~/Views/Shared/_Layout.cshtml" trong view AboutUs, trong khi Index action lại sử dụng đường dẫn là "_Layout". Khi một đường dẫn partial được cung cấp cho Razor view engine tìm kiếm file layout trong thư mục Views/{Controllers} trước tiên, và theo sau đó là thư mục Shared. Quá trình này được gọi là tìm kiếm View.

Section

ASP.NET Core cho phép bạn tạo một hoặc nhiều section cho layout. Section cần một cái tên và một thuộc tính chỉ ra xem nó có bắt buộc phải có trong các view con không. Phương thức RenderSection(string name, bool required:false) định nghĩa tên section.

@RenderSection("footer", required: false)

Thêm Section vào Layout

Mở layout ra và dán dòng lệnh sau vào sau nội dung:

<div>
    @RenderSection("Test", required: false)
</div>

Chúng ta định nghĩa một section tên "Test" với tham số required là false tức là không yêu cầu bắt buộc phải có section này trong view con.

Định nghĩa Section trong view

Giờ hãy vào trang View của Index và dán đoạn sau:

@{
    Layout = "_Layout";
}
<p>Here goes the content</p>
 
@section Test
{
    <p>Test Section</p>
}

Các section được định nghĩa với một khối lệnh Razor là @section bằng tên nó đi kèm. Chạy ứng dụng và kiểm tra xem các section đó có hiển thị sau content.

Tạo section bắt buộc

Thay đổi tham số required:true khi định nghĩa section trong layout như dưới đây:

@RenderSection("Test", required: true)

Giờ hãy chạy ứng dụng và vào URL /Home/AboutUs sau đó bạn nhìn thấy lỗi sau:

InvalidOperationException: The layout page ‘/Views/Shared/_Layout.cshtml’ cannot find the section ‘Test’ in the content page ‘/Views/Home/AboutUs.cshtml’.

Điều này xảy ra vì chúng ta không định nghĩa section "Test" trong view AboutUs

_ViewStart

Trong ví dụ trên, chúng ta định nghĩa layout và dùng nó cho các view. Định nghĩa layout trong tất cả các view thật khó để bảo trì. Cách đơn giải nhất là định nghĩa layout trong _ViewStart.cshtml.

Mục đích của file này là cài đặt giá trị mặc định cho các View khác trong folder và folder con của nó. Giờ hãy đến thư mục Views và tạo _ViewStart.cshtml trong thư mục Views và dán đoạn sau:

@{
    Layout = "_Layout";
}

Hãy bỏ hoặc comment đoạn code trên trong view AboutUs. Chạy ứng dụng và kiểm tra lại.

Loại bỏ Layout từ view

Vì chúng ta đã thêm file _ViewStart.cshtml vào thư mục Views nên layout giờ đã có thể áp dụng cho tất cả các View. Trong trường hợp bạn không muốn sử dụng layout cho view nào bạn chỉ cần đặt giá trị Layout là null.

@{
    Layout = null;
}

hoặc đặt giá trị cho Layout là một Layout khác:

@{
    Layout = "_someOtherLayout";
}

Bạn có thể tạo một file _ViewStart tách biệt trong thư mục Controller, vậy là bạn có thể ghi đè file _ViewStart từ thư mục cha.

Tác giả: Bạch Ngọc Toàn

Chú ý: Tất cả các bài viết trên TEDU.COM.VN đều thuộc bản quyền TEDU, yêu cầu dẫn nguồn khi trích lại trên website khác.

Lên trên