

Một số cải tiến trong ASP.NET Core, Razor Page, Model Binding, Gabbage collection
- 03-03-2025
- Toanngo92
- 0 Comments
Mục lục
ASP.NET Core MVC và Razor Pages
- Razor Pages lần đầu tiên được giới thiệu trong ASP.NET Core MVC 3.0.
- Đây là một công cụ giúp tạo các view theo mẫu MVC trong Visual Studio.
- Razor sử dụng cú pháp markup để nhúng mã server-side trong các ngôn ngữ như Visual Basic (VB) và C# vào trang web.
Cách hoạt động của Razor Engine:
- View Engine là một mô-đun linh hoạt có thể triển khai nhiều cú pháp mẫu khác nhau và giúp cải thiện năng suất.
- Khi một yêu cầu trang web được gửi từ người dùng, mã server-side được thực thi và kết quả trả về trình duyệt.
- Razor thực hiện các tác vụ phức tạp như truy cập cơ sở dữ liệu và tạo nội dung động trên trang.
Đặc điểm của Razor:
- Dễ sử dụng: Hỗ trợ tạo ứng dụng web bằng cách kết hợp giữa nội dung tĩnh (HTML) và nội dung động (C# hoặc VB).
- Đơn giản: Cho phép các nhà phát triển tạo ứng dụng web dễ dàng và hiệu quả.
- Tương thích: Razor tương tự như Active Server Pages eXtended (ASPX) nhưng dễ sử dụng hơn.
Các phần mở rộng tệp cho Razor View:
- .vbhtml: dành cho cú pháp VB.
- .cshtml: dành cho cú pháp C#.
Một số đặc điểm nổi bật của cú pháp Razor:
- Gọn nhẹ (Compact): Giảm thiểu số lượng ký tự và thao tác gõ phím.
- Dễ học (Easy to Learn): Hỗ trợ cả ngôn ngữ C# và VB.
- Hỗ trợ IntelliSense: Tự động hoàn thành cú pháp trong Visual Studio.
Quy tắc cú pháp Razor cho C#:
- Sử dụng
@{ ... }
cho các khối mã Razor. - Bắt đầu các biểu thức dòng đơn bằng dấu
@
. - Kết thúc các câu lệnh mã bằng dấu
;
. - Sử dụng từ khóa var để khai báo biến.
- Dùng dấu ngoặc kép
" "
để bao quanh chuỗi. - Tuân thủ phân biệt chữ hoa và chữ thường của C#.
Tạo ứng dụng MVC với Razor View
Các bước tạo ứng dụng Razor-based MVC:
- Mở Visual Studio 2022 và tạo một dự án mới.
- Trong cửa sổ Create a new Project, chọn ASP.NET Core Web App.



Nội dung HTML và mã Razor
- Trong một trang web Razor, có hai loại nội dung:
- Nội dung HTML: Được hiển thị trực tiếp trên trình duyệt.
- Mã Razor: Được máy chủ xử lý trước khi gửi đến trình duyệt.
- Để hiển thị nội dung từ mã phía máy chủ:
- Sử dụng cú pháp
@Variable_Name
để hiển thị biến. - Sử dụng
@DateTime.Now
để hiển thị ngày giờ hiện tại.
- Sử dụng cú pháp
- Không cần dấu chấm phẩy (
;
) khi kết thúc một biểu thức đơn dòng.
Ví dụ về mã Razor
Code Snippet 1: Hiển thị ngày giờ hiện tại
@page
<h1>Razor Demo</h1>
<h2>@DateTime.Now.ToShortDateString()</h2>
Kết quả hiển thị:
Razor Demo
28-02-2024
Code Snippet 2: Sử dụng biến trong Razor
@{
var date = DateTime.Now.ToShortDateString();
var message = "I am nervous!";
}
<h2>My exam is on: @date</h2>
<h3>@message</h3>
Kết quả hiển thị:
My exam is on: 28-02-2024
I am nervous!
Hiển thị nội dung trong thẻ <text>
Code Snippet 3A:
@{
var date = DateTime.Now.ToShortDateString();
string message = "Hello All!";
}
@:<text>Today's date is: @date</text>
@message
Code Snippet 3B:
@{
var date = DateTime.Now.ToShortDateString();
string message = "Hello All!";
}
<text>Today's date is:</text> @date <br />
@message
Kết quả hiển thị cho cả 3A và 3B:
Today's date is: 28-02-2024
Hello All!
Câu lệnh điều kiện If-Else trong Razor
Code Snippet 4: Kiểm tra năm nhuận
@if (DateTime.IsLeapYear(DateTime.Now.Year)) {
<p>@DateTime.Now.Year is a leap year.</p>
} else {
<p>@DateTime.Now.Year is not a leap year.</p>
}
Kết quả hiển thị:
2024 is a leap year.
Vòng lặp trong Razor
Code Snippet 5: Sử dụng vòng lặp for
@for (int i = 0; i < 4; i++) {
@i.ToString() <br />
}
Kết quả hiển thị:
0
1
2
3
Sử dụng đối tượng Model trong Razor View
Code Snippet 6: Hiển thị thông tin sinh viên
@model Student
<h2>Student Details:</h2>
<ul>
<li>Student ID: @Model.StudentId</li>
<li>Student Name: @Model.StudentName</li>
<li>Age: @Model.Age</li>
</ul>
Kết quả hiển thị:
Student Details:
- Student ID: 101
- Student Name: John Doe
- Age: 20
- Một biến có thể được khai báo bên trong khối mã Razor bằng dấu @{ … }.
- Các biến này sau đó được sử dụng trong phần HTML bằng cú pháp @VariableName.
Code Snippet 7: Khai báo và sử dụng biến trong Razor
@{
string str = "";
// Giả sử điều kiện đúng
if (3 > 0) {
str = "Hello World!";
}
}
<p>@str</p>
Kết quả hiển thị:
Hello World!
Bảng 7.1: Các lệnh Razor phổ biến
Lệnh Razor | Mô tả |
---|---|
@if | Đánh dấu sự bắt đầu của câu lệnh điều kiện if . |
@using | Cho phép sử dụng các namespace, package và class khác. |
@try, @catch, @finally | Được sử dụng để xử lý ngoại lệ. |
@inherits | Kế thừa class gốc trong Razor. |
Các cải tiến trong ASP.NET Core 7.0+
- MVC Model Binding đã được cải thiện, giúp ánh xạ dữ liệu từ HTTP request đến các model dễ dàng hơn.
- Hỗ trợ C# 10 và tối ưu hóa quá trình biên dịch Razor.
- Tăng cường bảo mật để giảm thiểu các lỗ hổng phổ biến.
- Cải thiện môi trường phát triển với Visual Studio 2022:
- Hỗ trợ IntelliSense tốt hơn.
- Cải thiện khả năng gỡ lỗi.
- Tích hợp tốt hơn với các hệ thống quản lý mã nguồn như Git.
MVC Model Binding
Giới thiệu về Model Binding
- Model Binding là quá trình ánh xạ dữ liệu từ HTTP request vào các đối tượng Model trong ASP.NET MVC.
- Nó giúp chuyển dữ liệu từ các trường form hoặc URL parameters vào các tham số trong các phương thức Controller.
Ví dụ:
- Nếu một phương thức yêu cầu tham số kiểu số nguyên (int) từ URL và không nhận được giá trị phù hợp, hệ thống sẽ gán giá trị mặc định là
0
.
Các đặc điểm mới trong ASP.NET Core
- [BindNever]:
- Ngăn không cho thuộc tính được ánh xạ từ dữ liệu HTTP request.
- Đảm bảo rằng một thuộc tính nhất định sẽ không bao giờ nhận dữ liệu từ phía client.
- [BindRequired]:
- Đánh dấu một thuộc tính là bắt buộc phải có dữ liệu.
- Nếu thiếu dữ liệu, sẽ tạo ra lỗi trong quá trình Model Binding.

- Visual Studio hỗ trợ hiển thị và làm việc với các thuộc tính như [BindNever] và [BindRequired] trực tiếp trên giao diện lập trình.
Code Snippet 8: Sử dụng [BindNever]
public class Employee
{
[BindNever]
public int EmployeeId { get; set; }
public string Name { get; set; }
}
Giải thích:
- Thuộc tính EmployeeId sẽ không bao giờ được ánh xạ dữ liệu từ HTTP request.
- Chỉ có thuộc tính Name sẽ nhận dữ liệu từ form hoặc URL.
C# Record Type
Giới thiệu về Record Type trong C#
- Record Type trong C# được sử dụng để truyền dữ liệu giữa Controller và API.
- Thường được dùng trong Model Binding để ánh xạ dữ liệu trong MVC controller hoặc Razor Page.
Ví dụ: Tạo một Record Movies
Code Snippet 9: Khai báo Record và sử dụng trong Controller
namespace WebApplication5.Controllers
{
public record Movies(string MoviesCode, string MoviesName, int MoviesBudget);
public class MoviesController : Controller
{
public IActionResult Index() => View();
[HttpPost]
public IActionResult Index(Movies mv)
{
return View();
}
}
}
Giải thích:
- Record Movies chứa 3 thuộc tính:
MoviesCode
,MoviesName
, vàMoviesBudget
. - MoviesController sử dụng Model Binding để nhận dữ liệu từ form và xử lý.
Ví dụ: Form nhập liệu và kiểm tra dữ liệu
Code Snippet 10: Form nhập liệu trong Razor View (Index.cshtml
)
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
<form>
<table>
<tr>
<td>Movie Code:</td>
<td>
<input asp-for="MoviesCode" />
<span asp-validation-for="MoviesCode"></span>
</td>
</tr>
<tr>
<td>Movie Name:</td>
<td>
<input asp-for="MoviesName" />
<span asp-validation-for="MoviesName"></span>
</td>
</tr>
<tr>
<td>Movie Budget:</td>
<td>
<input asp-for="MoviesBudget" />
<span asp-validation-for="MoviesBudget"></span>
</td>
</tr>
</table>
</form>
@model Movie
<p>Movie Code: @Model.MoviesCode</p>
Giải thích:
- Sử dụng asp-for để ánh xạ các trường nhập liệu với thuộc tính trong Record Movies.
- asp-validation-for được sử dụng để hiển thị thông báo lỗi khi nhập dữ liệu không hợp lệ.
Text.Json
Giới thiệu về Text.Json trong ASP.NET Core
- Text.Json là một thư viện tích hợp trong ASP.NET Core để làm việc với JSON.
- Hỗ trợ mã hóa/giải mã JSON sử dụng UTF-8 với hiệu suất cao.
Các thành phần chính của Text.Json
Thành phần | Mô tả |
---|---|
JsonSerializer | Hỗ trợ serialization và deserialization các đối tượng .NET sang JSON và ngược lại. |
JsonDocument | Cung cấp cách quản lý dữ liệu JSON theo cấu trúc mà không cần nạp toàn bộ dữ liệu vào bộ nhớ. |
JsonElement | Đại diện cho một giá trị trong một JsonDocument. |
Utf8JsonWriter | API để ghi nội dung JSON theo chuẩn UTF-8. |
Utf8JsonReader | API để đọc nội dung JSON mã hóa UTF-8. |
Ví dụ: Serialization và Deserialization với JsonSerializer
Code Snippet 11: Khai báo một class và thực hiện serialize/deserialize
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Giải thích:
- Employee là một class đơn giản với hai thuộc tính FirstName và LastName.
- Sử dụng JsonSerializer để chuyển đổi đối tượng Employee thành JSON và ngược lại.
Code Snippet 12: Serialization và Deserialization trong ASP.NET Core
@{
public IActionResult Index()
{
string Serialize;
string Deserialize;
Employee obj = new Employee { FirstName = "Tyler", LastName = "King" };
string json = JsonSerializer.Serialize(obj); // Thực hiện Serialization
Serialize = json;
var stringde = "{\"FirstName\":\"David\"}";
Employee anotherObject = JsonSerializer.Deserialize<Employee>(stringde); // Thực hiện Deserialization
Deserialize = anotherObject.FirstName;
return View();
}
}
Giải thích:
- Serialization:
- Đối tượng
Employee
được khởi tạo và sau đó chuyển đổi thành chuỗi JSON bằngJsonSerializer.Serialize()
. - Kết quả:
{"FirstName":"Tyler","LastName":"King"}
.
- Đối tượng
- Deserialization:
- Một chuỗi JSON khác
{"FirstName":"David"}
được chuyển đổi ngược lại thành đối tượngEmployee
bằngJsonSerializer.Deserialize()
. - Thuộc tính
FirstName
của đối tượng mới nhận giá trị"David"
.
- Một chuỗi JSON khác
Dump Debugging
Giới thiệu về Dump Debugging
- Dump Debugging là kỹ thuật thu thập và phân tích các heap dump từ tiến trình đang chạy của .NET Core.
- Microsoft đã phát hành công cụ dotnet-dump để hỗ trợ thu thập và phân tích dump, giúp chẩn đoán sự cố trong các ứng dụng ASP.NET Core.
Các lệnh chính của dotnet-dump
- dotnet-dump collect
- Thu thập dữ liệu dump dựa trên tên tiến trình, ID tiến trình và các tham số khác.
- Cú pháp:
dotnet-dump collect [-h|--help] [-p|--process-id] [-n|--name] [--type] [-o|--output] [--diag]
- dotnet-dump analyze
- Phân tích dữ liệu dump đã thu thập.
- Giúp khám phá nguyên nhân gây ra lỗi hoặc treo ứng dụng.
- Cú pháp: dotnet-dump analyze <dump_path> [-h | –help] [-c | –command]
Lợi ích của Dump Debugging
- Chẩn đoán lỗi khó tái tạo:
- Dump Debugging rất hiệu quả để phân tích các lỗi chỉ xảy ra trong môi trường sản xuất.
- Phân tích hiệu suất:
- Giúp phát hiện các vấn đề như rò rỉ bộ nhớ, lỗi quản lý luồng hoặc hiệu suất chậm.
- Kiểm tra Garbage Collection (GC):
- Xác định các vấn đề liên quan đến bộ thu gom rác trong .NET Core.
Thư viện Runtime (Runtime Libraries)
- Tất cả các thư viện lớp .NET đều bao gồm các thư viện runtime, được mở rộng thông qua NuGet packages.
- Quản lý các thư viện runtime cho kiểu tham chiếu nullable rất quan trọng để cải thiện hiệu suất và giảm thiểu lỗi NullReferenceException.
- Đảm bảo rằng các kiểu tham chiếu nullable được khai báo đúng cách giúp cải thiện khả năng tương thích với .NET Standard 2.1.
- Để bật tính năng C# 10 và thêm chú thích (annotations) cho các kiểu tham chiếu nullable khi làm việc với thư viện .NET Standard 2.0, hãy sử dụng cấu hình sau trong tệp dự án:
<LangVersion>latest</LangVersion>
Garbage Collection (Bộ thu gom rác – GC)
- Garbage Collector (GC) giúp quản lý bộ nhớ tự động trong .NET Framework.
- Điều này có nghĩa là lập trình viên không cần phải tự giải phóng bộ nhớ bằng tay.
- GC quản lý cấp phát bộ nhớ và vòng đời của đối tượng, giúp:
- Giảm thời gian downtime của ứng dụng.
- Tránh lỗi do truy cập vào đối tượng đã bị giải phóng.
- Không cần giải phóng thủ công đối tượng trong .NET, vì GC sẽ tự động thu hồi bộ nhớ khi đối tượng không còn được sử dụng.
Cách hoạt động của GC
- GC quản lý bộ nhớ thông qua Managed Heaps (vùng nhớ được quản lý).
- Heap là một khu vực bộ nhớ được dự trữ khi ứng dụng khởi động.
- GC kiểm tra Root của ứng dụng để xác định các đối tượng không còn cần thiết.
- Khi một ứng dụng ASP.NET Core bắt đầu, GC cấp phát bộ nhớ cho các heap và phân loại đối tượng thành 3 thế hệ (generations): Thế hệ (Generation) Mô tả Gen 0 Đối tượng có tuổi thọ ngắn, được thu gom bởi GC thường xuyên. Gen 1 Đối tượng có tuổi thọ trung bình, GC thu gom ít thường xuyên hơn. Gen 2 Đối tượng có tuổi thọ dài, ít bị GC thu gom.
- Các đối tượng có vòng đời dài (Gen 2) sẽ không được thu gom thường xuyên để tối ưu hiệu suất.
Liên hệ giữa Dump Debugging và Garbage Collection
- Dump Debugging (chẩn đoán dump) có thể giúp kiểm tra cách GC hoạt động.
- Bằng cách phân tích heap dumps, lập trình viên có thể xác định nguyên nhân gây rò rỉ bộ nhớ hoặc hiệu suất chậm.
- dotnet-dump analyze hỗ trợ khám phá cách bộ nhớ được sử dụng và cách GC hoạt động trong ứng dụng.