C# cơ bản .NET Core

View Component trong Razor

View Component nó giống như Partial View, Partial Page, chúng cung cấp khả năng phát sinh HTML được sử dụng lại nhiều lần, trong nhiều trang. Nếu có thể sử dụng View Component thay cho Partial View, Partial Page.

Tạo View Component

Một View Component nó gồm có một file khai báo lớp, lớp này phải kế thừa từ ViewComponent có chức năng xử lý logic, cung cấp dữ liệu và một file .cshtml là thành phần View sinh HTML.

  • Tên lớp phải có phần hậu tố ViewComponent hoặc phải có thuộc tính [ViewComponent]
  • Lớp phải triển khai phương thức Invoke trả về IViewComponentResult hoặc triển khai lớp InvokeAsync và trả về Task<IViewComponentResult>
  • Thường thì file .cshtml của View Component đặt tên là Default.cshtml
  • Component nên tạo ra trong các thư mục như /Pages/Components/NameComponent/, /Views/Shared/Components/NameComponent/

Ta thực hành tạo ra một ViewComponent đặt tên là ViewProduct, nó dùng để dựng HTML về một sản phẩm, giả sử thông tin về sản phẩm lưu trong biến kiểu dynamic (cho nhanh ở ví dụ này) có các trường Name, Description, Price.

Ta sẽ tạo các thành nó ở thư mục /Page/Components/ViewProduct/ (chú ý về cấu trúc thư mục)

Các Component lưu the đường dẫn như sau:

/Views/{Controller Name}/Components/{View Component Name}/{View Name}
/Views/Shared/Components/{View Component Name}/{View Name}
/Pages/Shared/Components/{View Component Name}/{View Name}

/Page/Components/ViewProduct/ViewProduct.cs

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace MyViewComponent {
    
  // Tên lớp ViewProductViewComponent thì không cần thuộc tính [ViewComponent]
  [ViewComponent]
  public class ViewProduct : ViewComponent { 
    // product là sản phẩm hiện thị, dùng dynamic cho nhanh ở ví dụ này,
    // thống nhất nó có cấu trúc gồm các thuộc tính: Name, Description, Price
    dynamic product; 
    // Nếu khởi tạo có tham số, thì nó là dịch vụ cần được Inject và
    // Dịch vụ Inject vào cũng cần đăng ký ở ConfigureServices trong Startup
    public ViewProduct () {

    } 
    // Dùng async Task<IViewComponentResult> InvokeAsync
    // nếu dùng kỹ thuật bất đồng bộ
    public IViewComponentResult Invoke (dynamic product) {
      this.product = product;
      return View (product); // Nếu khác Default.cshtml thì trả về View("abc", product) cho abc.cshtml

    }
  }
}

/Page/Components/ViewProduct/Default.cshtml

@model dynamic
<div class="card m-4">
   <div class="card-header bg-danger text-light">@Model.Name</div>
   <div class="card-body">
       <p>Thông tin @Model.Description</p>
       <p>Giá: @Model.Price</p>
   </div>
</div>

Sử dụng View Component

Để sử dụng ViewCompoent trong Razor thì sử dụng InvokeAsync trong thuộc tính Component với tham số là tên ViewComponent và tham số của Invoke trong ViewComponent ví dụ gọi View Component trên

@{
  dynamic vproduct = new {
    Name = "Sản phẩm ABC",
    Description = "Thông tin chi tiết về ABC ... ",
    Price = "1000"
  };
}

@await Component.InvokeAsync("ViewProduct", vproduct);

Kết quả

view components

Trong Controller, PageModel có thể trả về ngay ViewComponent bằng cách gọi phương thức ViewComponent

return ViewComponent("ViewCompoentName", arguments);

Trong đó arguments là tham số của Invoke

Xây dựng trang thông báo - chuyển hướng với ViewComponent

Trong ứng dụng Web nhiều trường hợp khi người dùng thực hiện một tác vụ bạn muốn có một trang thông báo cho người dùng biết kết quả sau đó chuyển hướng đến một trang đích khác. Ví dụ, khi người dùng đăng ký tài khoản xong, xuất hiện một hộp thoại cho biết một email đã được gửi đi có nội dung hướng dẫn kích hoạt tài khoản, thông báo này hiện thị vài giây sau đó chuyển hướng về trang đích nào đó (như trang đăng nhập).

Tạo một dự án ASP.NET Core Razor Page bằng lệnh:

dotnet new webapp

Ở đây sẽ áp dụng cách chuyển hướng bằng cách thiết lập HEADER của HTTP Respone, xây dựng một View Component đặt tên là MessagePage lưu chúng ở thư mục Views/Shared/Components/MessagePage với 2 file có nội dung như sau:

Views/Shared/Components/MessagePage/MessagePage.cs

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace XTLASPNET
{
    [ViewComponent]
    public class MessagePage : ViewComponent
    {
        public const string COMPONENTNAME = "MessagePage";
        // Dữ liệu nội dung trang thông báo
        public class Message {
            public string title {set; get;} = "Thông báo";     // Tiêu đề của Box hiện thị
            public string htmlcontent {set; get;} = "";         // Nội dung HTML hiện thị
            public string urlredirect {set; get;} = "/";        // Url chuyển hướng đến
            public int secondwait {set; get;} = 3;              // Sau secondwait giây thì chuyển
        }
        public MessagePage() {}
        public IViewComponentResult Invoke(Message message) {
            // Thiết lập Header của HTTP Respone - chuyển hướng về trang đích
            this.HttpContext.Response.Headers.Add("REFRESH",$"{message.secondwait};URL={message.urlredirect}");
            return  View(message);
        }
    }
}

Views/Shared/Components/MessagePage/Default.cshtml

@model XTLASPNET.MessagePage.Message
@{
    Layout = "_Layout";
    ViewData["Title"] = @Model.title;
}
<div class="card m-4">
   <div class="card-header bg-danger text-light">
       <h4>@Model.title</h3>
   </div>
   <div class="card-body">
       @Html.Raw(Model.htmlcontent)
   </div>
   <div class="card-footer">
       Chuyển đến - <a href="@Model.urlredirect">@Model.urlredirect</a>
   </div>
</div>

Kiểm tra: giả sử truy cập trang https://localhost:5001/privacy không hiện thị nội dung View của trang đó nữa mà thay bằng một thông báo rồi chuyển hướng về trang chủ

Mở file Privacy.cshtml.cs sửa OnGet thành:

public IActionResult OnGet()
{
    return ViewComponent("MessagePage", new XTLASPNET.MessagePage.Message {
        title = "Thông báo quan trọng",
        htmlcontent = "Đây là <strong>Nội dung HTML</strong>",
        secondwait = 5,
        urlredirect = "/"
    });
}

Truy cập trang kết quả như sau (thông báo sau 5s chuyển về trang chủ):

viewcomponent01

Mã nguồn: ASP_NET_CORE/razor09.messsagepage


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