Phát triển Client Side sử dụng ASP.NET Core MVC
- 04-12-2024
- Toanngo92
- 0 Comments
Mục lục
Chế độ xem bố cục trong ASP.NET Core MVC
Trong các ứng dụng web, một phần cụ thể của giao diện người dùng là giống nhau trên tất cả các trang. Các phần cụ thể này bao gồm phần đầu trang, phần chân trang, và điều hướng bên trái và phải như được hiển thị trong Hình 4.1.
- HEADER SECTION: Phần đầu trang.
- FOOTER SECTION: Phần chân trang.
- LEFT ACTION/RIGHT ACTION: Điều hướng trái/phải.
- CHILD AREA: Khu vực nội dung chính.
Trong ASP.NET Core MVC, cơ chế giao diện người dùng được gọi là Layout View chứa các phần thông dụng này. Điều này đảm bảo rằng mã của các phần này không được lặp lại trên mỗi trang. Bố cục này tương tự như khái niệm trang chính trong các ứng dụng ASP.NET Web Forms thông thường.
Các bố cục thường được chia sẻ giữa nhiều giao diện; do đó, chúng được lưu trữ trong thư mục Shared. Ví dụ, trong dự án MyCodeFirstApproachDemo, tệp bố cục được gọi là _Layout.cshtml được tạo ra như minh họa trong Hình 4.2.
Code Snippet 1: Nội dung của tệp _Layout.cshtml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - MyCodeFirstApproachDemo</title>
<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="/css/site.css" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MyCodeFirstApproachDemo</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2022 - MyCodeFirstApproachDemo - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="/lib/jquery/dist/jquery.min.js"></script>
<script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="/js/site.js" asp-append-version="true"></script>
@RenderSection("Scripts", required: false)
</body>
</html>
Sử dụng bố cục View
Trang này mô tả cách sử dụng tệp _ViewStart.cshtml
để đặt bố cục mặc định (_Layout
) cho các view trong ứng dụng ASP.NET Core MVC. Dưới đây là phần mã trong tệp _ViewStart.cshtml
:
@{
Layout = "_Layout";
}
- Tệp
_ViewStart.cshtml
được sử dụng để định nghĩa bố cục mặc định cho tất cả các view trong ứng dụng. - Trong đoạn mã trên,
Layout = "_Layout";
nghĩa là tất cả các view sẽ sử dụng bố cục_Layout.cshtml
trừ khi được ghi đè riêng trong từng view cụ thể.
Tạo một tệp _LayoutVersion2.cshtml với màu background thay đổi như code sinppet 2:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - MyCodeFirstApproachDemo</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body style="background-color:aqua;">
<header>
<nav class="navbar navbar-expand-sm navbar-light bg-light border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MyCodeFirstApproachDemo</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2022 - MyCodeFirstApproachDemo -
<a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@RenderSection("Scripts", required: false)
</body>
</html>
Trong tệp _ViewStart.cshtml nằm trong thư mục Home View, bạn có thể thêm _layoutVersion2.cshtml để hiển thị bố cục đã thay đổi như được minh họa trong Hình 4.7 và 4.8.
Triển khai định kiểu (Implementing Styles)
Xem xét một ví dụ minh họa cách triển khai kiểu dáng trong một ứng dụng. Trong ví dụ này, ứng dụng MyCodeFirstApproachDemo được mở trong Visual Studio 2022 như minh họa trong Hình 4.9.
Để mở thư mục css, js, và lib được sử dụng trong ứng dụng, hãy mở rộng thư mục wwwroot như minh họa trong Hình 4.10.
Trong thư mục lib, có một thư mục con bootstrap với một thư mục css bên trong. Bootstrap được sử dụng để mở rộng các chức năng của CSS và JS. Nó làm cho các ứng dụng trở nên phản hồi tốt hơn và có giao diện tinh tế hơn. Trong ví dụ này, thư mục bootstrap chứa các tệp CSS được tải xuống hoặc tải trước trong ứng dụng từ các tài nguyên bên ngoài như getbootstrap.com hoặc Twitter Bootstrap, như được minh họa trong Hình 4.11.
Trong ví dụ này, thư mục css chứa tệp site.css được sử dụng để thêm các đặc tả cho ứng dụng. Các bước thực hiện như sau:
Bước 1: Mở tệp site.css từ Solution Explorer, đoạn mã mặc định trong tệp này được hiển thị như trong Code Snippet 3.
a.navbar-brand {
white-space: normal;
text-align: center;
word-break: break-all;
}
.demo_css {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
/* Provide sufficient contrast against white background */
a {
color: #0366d6;
}
.btn-primary {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
Bước 2: Lớp CSS có thể được tạo để định nghĩa các kiểu. Ví dụ, trong một lớp demo_css, ba kiểu khác nhau là color, background-color, và border-color được chỉ định như trong Code Snippet 4.
.demo_css {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
Bước 3: Mở tệp _Layout.cshtml để hiển thị việc bao gồm các tệp CSS như được minh họa trong Hình 4.12.
Chú thích Dữ liệu (Data Annotations)
Xác thực dữ liệu là một phần quan trọng của phát triển ứng dụng, đặc biệt khi xử lý dữ liệu lớn. Dữ liệu cần được phân tích dựa trên các yêu cầu hoặc tiêu chí nhất định. Người dùng cũng phải cung cấp dữ liệu chính xác. Do đó, việc xác thực dữ liệu là rất quan trọng.
ASP.NET MVC có một namespace được tích hợp sẵn với các lớp để xác thực dữ liệu – System.ComponentModel.DataAnnotations.
Một số lớp thuộc namespace này bao gồm:
- RequiredAttribute: Thuộc tính này chỉ ra rằng một giá trị cần được nhập bởi người dùng.
- RangeAttribute: Thuộc tính này chỉ định phạm vi số mà dữ liệu phải nằm trong.
- PhoneAttribute: Chỉ ra rằng giá trị trong trường này phải là một số điện thoại hợp lệ.
- UrlAttribute: Cho phép nhà phát triển áp dụng quy tắc để thực thi các URL được chỉ định hợp lệ. Nó cũng có thể đảm bảo rằng người dùng chỉ có thể nhập các URL hợp lệ.
- EmailAddressAttribute: Thuộc tính này thường được sử dụng để giới hạn người dùng chỉ định địa chỉ email.
Định tuyến (Routing)
Định tuyến trong ASP.NET MVC là về việc kết nối giữa các yêu cầu HTTP đến và chuyển tiếp chúng tới các điểm cuối có thể thực thi, cho phép hành động yêu cầu được hoàn thành. Các điểm cuối là phần duy nhất thực hiện công việc thực tế. Quy trình khớp điểm cuối có thể trích xuất giá trị từ URL của một yêu cầu và sử dụng chúng để xử lý thêm. Định tuyến cũng có thể tạo URL ánh xạ tới các điểm cuối bằng cách lấy thông tin từ ứng dụng.
Định tuyến là một chiến lược theo dõi các yêu cầu và sau đó, ánh xạ chúng tới các bộ điều khiển và phương thức của chúng. Bản đồ này được định nghĩa trong hệ thống và có thể được cập nhật bởi nhà phát triển khi cần. Việc thêm tuyến đường vào pipeline xử lý yêu cầu cho phép ánh xạ thủ công.
Do đó, tùy thuộc vào các tuyến đường được đặt trong một ứng dụng, framework ASP.NET Core đưa ra các yêu cầu đến bằng cách ánh xạ URL hoặc yêu cầu tới các phương thức hành động tương ứng như minh họa trong Code Snippets 5 và 6.
Code snippet 5:
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}
Code snippet 6:
public IActionResult Index()
{
return View();
}
public IActionResult Info(int id)
{
return View();
}
Đối với một ứng dụng đơn lẻ, có thể cấu hình nhiều tuyến đường. Thông tin bổ sung như các cài đặt mặc định, ràng buộc, và bộ xử lý thông điệp có thể được cung cấp trên mỗi tuyến đường. Một mẫu tuyến đường được sử dụng làm mặc định. Một mẫu tuyến đường so sánh với tuyến đường mặc định được sử dụng bởi hầu hết các ứng dụng với bộ điều khiển và chế độ xem.
Hơn nữa, các tuyến đường khác có thể được thêm vào như được minh họa trong đoạn mã Code Snippet 7.
app.MapControllerRoute(
name: "customer",
pattern: "customer/{*info}",
defaults: new { controller = "Customer", action = "Info" });
Dependency Injection (Tiêm phụ thuộc)
Tiêm phụ thuộc (Dependency Injection – DI) là một khái niệm rất đơn giản, mặc dù việc triển khai của nó có vẻ phức tạp. Có ba thuật ngữ liên quan đến ngữ cảnh này. Tuy nhiên, chúng không đồng nghĩa và bao gồm:
- Dependency Injection (DI): Tiêm phụ thuộc.
- Inversion of Control (IoC): Đảo ngược điều khiển.
- Dependency Inversion Principle (DIP): Nguyên tắc đảo ngược phụ thuộc.
Lợi ích của DI bao gồm:
- Tăng khả năng mở rộng và tái sử dụng mã.
- Dễ dàng kiểm tra đơn vị do sự cô lập của các thành phần.
- Cải thiện độ bảo trì và giảm sự phụ thuộc chặt chẽ giữa các lớp.
IoC (Đảo ngược quyền kiểm soát) là khái niệm bao quát trong đó DI là một phần. Nguyên lý đảo ngược phụ thuộc (DIP) khuyến nghị rằng cả các mô-đun cấp cao và cấp thấp nên phụ thuộc vào trừu tượng thay vì chi tiết.
DIP tuyên bố rằng:
- Các mô-đun cấp cao và cấp thấp đều phải phụ thuộc vào trừu tượng.
- Các chi tiết nên phụ thuộc vào trừu tượng, không phải ngược lại.
Tạo ứng dụng một trang (Single Page Applications – SPA)
SPA là một ứng dụng web chỉ tải một trang HTML duy nhất và cập nhật nội dung của trang đó khi cần mà không cần tải lại toàn bộ trang. Công nghệ này sử dụng HTML tĩnh, CSS và JavaScript được cung cấp bởi máy chủ. AJAX đóng vai trò quan trọng trong kiến trúc này, cho phép yêu cầu dữ liệu không đồng bộ từ máy chủ và cập nhật trang mà không cần tải lại. Điều này tạo ra trải nghiệm người dùng linh hoạt và mượt mà hơn.
Lợi ích của SPA (Single Page Application) so với các ứng dụng nhiều trang:
- Tốc độ tải nhanh hơn:
- Trong suốt vòng đời của ứng dụng, hầu hết tài nguyên (HTML, CSS, JavaScript) chỉ được tải một lần. Điều này giảm lượng dữ liệu được truyền qua lại giữa máy khách và máy chủ, giúp SPA nhanh hơn.
- Trải nghiệm người dùng mượt mà hơn:
- SPA cung cấp giao diện hợp nhất và quy trình phát triển đơn giản hóa. Các trang hoặc nội dung mới không cần viết lại vì tất cả đều xử lý trên cùng một giao diện. Việc phát triển có thể dựa trên các URL như
http://file/URL
mà không cần phụ thuộc vào bất kỳ máy chủ nào.
- SPA cung cấp giao diện hợp nhất và quy trình phát triển đơn giản hóa. Các trang hoặc nội dung mới không cần viết lại vì tất cả đều xử lý trên cùng một giao diện. Việc phát triển có thể dựa trên các URL như
- Dễ dàng kiểm tra và giám sát:
- Các thao tác mạng, phân tích thành phần trang, và dữ liệu được liên kết dễ dàng giám sát trong SPA, đặc biệt khi sử dụng các công cụ như Chrome.
- Tái sử dụng backend:
- Backend tương tự có thể được sử dụng cho ứng dụng web và các ứng dụng di động gốc, giúp tiết kiệm tài nguyên và giảm thiểu sự phức tạp trong phát triển.
- Lưu trữ cục bộ hiệu quả:
- Dữ liệu có thể được lưu trữ cục bộ. Khi một ứng dụng cần truy xuất dữ liệu, dữ liệu sẽ được lưu trữ và sử dụng ngay cả trong chế độ ngoại tuyến.
SPA cải thiện đáng kể trải nghiệm người dùng, đặc biệt cho các ứng dụng có thao tác nhanh chóng và giao diện cảm ứng. Điều này làm cho SPA trở thành lựa chọn lý tưởng trong các hệ thống hiện đại, như ki-ốt thông tin hoặc điểm bán hàng sử dụng màn hình cảm ứng.
Các bước khởi tạo cơ bản SPA (Single Page Application):
Mở Visual Studio 2022:
Chọn mẫu dự án SPA:
SPA trên nền tảng ASP.NET Core có thể tích hợp với các framework phổ biến khác như Angular, React, hoặc Vue. Microsoft đã cung cấp mẫu SPA trong phiên bản đầu tiên của ASP.NET Core và liên tục duy trì, cập nhật nó.
Thay đổi phiên bản Target Framework như hình 4.17:
Solution Explorer:
Mở Solution Explorer, một thư mục có tên ClientApp sẽ được tạo ra. Thư mục này chứa tệp package.json, như hiển thị trong Hình 4.18.
Lúc này, nhà phát triển có thể chọn chạy ASP.NET Core với SPA sử dụng Razor view hoặc Angular ở chế độ độc lập.
Mở tệp Startup.cs:
- Từ dự án chính, mở tệp Startup.cs để xem hai lệnh gọi:
- UseSpaStaticFiles: Sử dụng để lắng nghe các yêu cầu liên quan đến tệp tĩnh được tạo bởi Angular-CLI.
- UseSpa: Sử dụng để định cấu hình Angular hoặc các công nghệ SPA tương tự.
- Mã minh họa được thể hiện trong Hình 4.19.
- Phát triển SPA:
- Lập trình có thể được thực hiện trong ứng dụng AngularJS Web, trong đó các phần Model, View, và Controller được cung cấp để triển khai SPA.
- Ngoài Angular, React hoặc các công nghệ khác có sẵn với ASP.NET Core cũng có thể được sử dụng để tạo SPA.
Xác thực phía Client và Server
Xác thực là một khía cạnh quan trọng trong các ứng dụng web, có thể được thực hiện tại:
- Phía client (trình duyệt của người dùng).
- Phía server.
Xác thực phía máy khách
- Ưu điểm:
- Cải thiện trải nghiệm người dùng do mọi đầu vào được xác thực ngay trên trình duyệt.
- Các ngôn ngữ như JavaScript thường được sử dụng để xác thực phía client. Ví dụ: Khi nhập một email không hợp lệ, thông báo lỗi sẽ xuất hiện trước khi gửi biểu mẫu.
- Nhược điểm:
- Phụ thuộc vào ngôn ngữ JavaScript. Nếu người dùng tắt JavaScript, xác thực phía client có thể bị bỏ qua, dẫn đến dữ liệu nguy hiểm gửi đến server.
Tạo tệp CreateStudent.cshtml
Mã ví dụ Code Snippet 8:
@page
@model StudentManagement.Pages.Student.CreateStudentJQModel
@{
ViewData["Title"] = "Create Student";
}
<h2>Create Student - Validation using jQuery</h2>
<form method="post" onsubmit="return validateForm()">
<table class="table table-bordered">
<tr>
<td>Student Name</td>
<td>
<input asp-for="StudentName" /><br />
<span id="validationName" asp-validation-for="StudentName" style="color:red"></span>
</td>
</tr>
<tr>
<td>Student Email</td>
<td>
<input asp-for="EmailId" /><br />
<span id="validationEmail" asp-validation-for="EmailId" style="color:red"></span>
</td>
</tr>
<tr>
<td>Date of Join</td>
<td>
<input asp-for="DateOfJoin" /><br />
<span id="validationDOJ" asp-validation-for="DateOfJoin" style="color:red"></span>
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" id="submitbutton" value="Submit" />
</td>
</tr>
</table>
</form>
Để xác thực form, có thể sử dụng Client Side Validation:
<script type="text/javascript">
function validateForm() {
var isValidForm = true;
var nameValue = document.getElementById("StudentName").value;
var emailValue = document.getElementById("EmailId").value;
var dojValue = document.getElementById("DateOfJoin").value;
// Validate Student Name
if (nameValue == null || nameValue === "") {
document.getElementById("validationName").textContent = "Student Name is required.";
isValidForm = false;
}
// Validate Email
if (emailValue == null || emailValue === "") {
document.getElementById("validationEmail").textContent = "Student Email is required.";
isValidForm = false;
}
// Validate Date of Join
if (dojValue == null || dojValue === "") {
document.getElementById("validationDOJ").textContent = "Date of Join is required.";
isValidForm = false;
}
return isValidForm;
}
</script>
Mã trên tải các thư viện cần thiết từ CDN để hỗ trợ tính năng xác thực không xâm phạm (Unobtrusive Validation).
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.3.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.14.0/jquery.validate.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/mvc/5.2.3/jquery.validate.unobtrusive.min.js"></script>
Tích hợp Data Annotation trong Model
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.ComponentModel.DataAnnotations;
namespace StudentManagement.Pages.Student {
public class CreateStudentJQModel : PageModel {
[Required]
public string StudentName { get; set; }
[Required]
[EmailAddress]
public string EmailId { get; set; }
[Required]
[DataType(DataType.Date)]
public DateTime DateOfJoin { get; set; }
public void OnGet() {
}
}
}
Mô Tả Quy Trình Hoạt Động
- Thêm chú thích xác thực (Data Annotation) vào thuộc tính trong
CreateStudentJQModel
.Required
để yêu cầu không để trống.EmailAddress
để xác thực đúng định dạng email.DataType(DataType.Date)
để định nghĩa ngày.
- HTML sinh ra sẽ tự động thêm thuộc tính
data-*
cho các trường xác thực. - Thư viện jQuery Validate sử dụng các thuộc tính
data-*
để xử lý xác thực phía client.
Xác thực phía máy chủ (Server-side Validation)
Xác thực phía máy khách thường được ưu tiên hơn vì nhanh hơn và được thực hiện trước khi dữ liệu đầu vào của người dùng được gửi tới máy chủ. Tuy nhiên, nó dễ bị tổn thương hơn vì người dùng có thể bỏ qua quá trình xác thực hoặc gửi dữ liệu đầu vào đáng ngờ có thể ảnh hưởng đến máy chủ. Do đó, xác thực phía máy chủ luôn quan trọng, an toàn và đảm bảo dữ liệu đầu vào do người dùng gửi được kiểm tra chính xác.
Trong ASP.NET, điều này được thực hiện bằng các ngôn ngữ lập trình phía máy chủ như C# hoặc VB.NET. Nếu dữ liệu đầu vào của người dùng không hợp lệ, một thông báo lỗi sẽ được gửi trở lại trang web. Việc xác thực phía máy chủ luôn an toàn và đáng tin cậy.
Các bước thực hiện xác thực phía máy chủ:
- Thêm thuộc tính chú thích dữ liệu (Data Annotation) vào thuộc tính của lớp
ViewModel
. Các thuộc tính này xác định quy tắc xác thực và liên kết chúng vớiModelState
. - Cập nhật chế độ xem (View) để thêm mã xác thực dữ liệu. Điều này giúp người dùng dễ dàng nhập dữ liệu theo quy tắc xác thực mà không gặp lỗi.
- Xác minh trạng thái mô hình (ModelState) bằng cách kiểm tra thuộc tính
ModelState.IsValid
trong bộ điều khiển (controller). Nếu hợp lệ, dữ liệu được xử lý; nếu không, trả lại thông báo lỗi.
Vai trò của Data Annotation:
Các thuộc tính chú thích dữ liệu đóng vai trò quan trọng trong việc xác thực giá trị của các thuộc tính trong lớp ViewModel
. Quá trình xác thực kiểm tra xem dữ liệu đầu vào có phù hợp với quy tắc được xác định trong mô hình hay không. Nếu không, thuộc tính ModelState.IsValid
sẽ trả về giá trị false
và hiển thị thông báo lỗi.
Bắt đầu từ mô hình (Model) -> Thêm chú thích dữ liệu (Data Annotation) -> Sinh HTML -> Xác thực không xâm phạm phía máy khách -> Xác thực phía máy chủ.
Các thuộc tính chú thích dữ liệu (Data Annotation Attributes) thường được sử dụng bao gồm:
- Required: Một chỉ dẫn rằng thuộc tính là bắt buộc.
- Range: Phạm vi tối thiểu và tối đa của giá trị được phép.
- MinLength: Độ dài tối thiểu của chuỗi đầu vào.
- MaxLength: Độ dài tối đa của chuỗi đầu vào.
- RegularExpression: Xác thực giá trị dựa trên mẫu biểu thức chính quy.
Bao gồm không gian tên (namespace) cho thuộc tính chú thích dữ liệu: Các thuộc tính chú thích dữ liệu có sẵn trong System.ComponentModel.DataAnnotations.
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using Validation.Models;
namespace Validation.Models {
public class CreateStudentViewModel {
[Required(ErrorMessage = "Student Name is required")]
public string Name { get; set; }
[Required(ErrorMessage = "Student Class is required")]
[MinLength(5, ErrorMessage = "Minimum length of Class should be 5 characters")]
public string Class { get; set; }
[Required]
[Range(0, 100)]
public decimal Marks { get; set; }
}
}
Giải thích mã:
- Thuộc tính
Required
:- Xác định rằng các trường như Name, Class, và Marks là bắt buộc.
- Nếu xác thực không thành công, thông báo lỗi được hiển thị bằng cách sử dụng thuộc tính ErrorMessage.
- Thuộc tính
MinLength
vàRange
:- MinLength(5): Yêu cầu chiều dài tối thiểu của trường “Class” là 5 ký tự.
- Range(0, 100): Giá trị của trường “Marks” phải nằm trong khoảng từ 0 đến 100.
Khi xảy ra lỗi xác thực, thông báo lỗi sẽ hiển thị bên dưới trường tương ứng trong màu đỏ. Thẻ <span>
được sử dụng để hiển thị thông báo lỗi xác thực, được định nghĩa bởi thuộc tính asp-validation-for.
Ví dụ, mã này sẽ hiển thị thông báo lỗi xác thực nếu điều kiện không được đáp ứng.
Code Snippet 14: Biểu mẫu HTML với xác thực ASP.NET MVC
<form asp-controller="Student" asp-action="Index">
<table>
<tr>
<td><label asp-for="Name"></label></td>
<td><input asp-for="Name" /></td>
<td><span asp-validation-for="Name" style="color:red"></span></td>
</tr>
<tr>
<td><label asp-for="Class"></label></td>
<td><input asp-for="Class" /></td>
<td><span asp-validation-for="Class" style="color:red"></span></td>
</tr>
<tr>
<td><label asp-for="Marks"></label></td>
<td><input asp-for="Marks" /></td>
<td><span asp-validation-for="Marks" style="color:red"></span></td>
</tr>
<tr>
<td colspan="2"><input type="submit" id="submitbutton" value="Submit" /></td>
</tr>
</table>
</form>
iải thích:
- Thẻ
<span>
vớiasp-validation-for
:- Thuộc tính này liên kết thông báo lỗi xác thực với trường tương ứng trong ViewModel.
- Khi có lỗi, thông báo lỗi xác thực sẽ hiển thị dưới trường cụ thể.
Dựa trên các thuộc tính chú thích dữ liệu (Data Annotation) được xác định trong ViewModel và dữ liệu đầu vào, trạng thái ModelState được cập nhật tự động:
- Trong phương thức Index, nếu
ModelState.IsValid
trả vềtrue
, dữ liệu được lưu vào cơ sở dữ liệu. - Nếu
ModelState
không hợp lệ, dữ liệu không được lưu và lỗi xác thực sẽ hiển thị trên biểu mẫu.
Code Snippet 15: Cập nhật ModelState
[HttpPost]
public IActionResult Index(StudentAddViewModel studentAddViewModel) {
if (ModelState.IsValid) {
using (var db = new StudentDbContext())
{
Student newStudent = new Student()
{
Name = studentAddViewModel.Name,
Class = studentAddViewModel.Class,
Marks = studentAddViewModel.Marks
};
db.Students.Add(newStudent);
db.SaveChanges();
// Điều hướng tới phương thức GET Index
return RedirectToAction("Index");
}
using (var db = new StudentDbContext())
{
studentAddViewModel.StudentList = db.Students.ToList();
return View(studentAddViewModel);
}
}
}
Hiển thị thông báo lỗi:
- Khi một trường không đáp ứng điều kiện xác thực:
- Thông báo lỗi sẽ được hiển thị ngay bên dưới trường cụ thể.
- Các chú thích dữ liệu (Data Annotation) như
Required
,MinLength
, hoặcMaxLength
sẽ xác định loại lỗi.
- Cách hiển thị lỗi mặc định:
- Sử dụng tên của trường đã khai báo trong ViewModel để hiển thị lỗi.
- ASP.NET MVC tự động xử lý các thông báo lỗi dựa trên các chú thích dữ liệu.
Lưu đồ tổng quát các bước trong xác thực phía server:
- Người dùng nhập dữ liệu:
- Gửi biểu mẫu với thông tin đầu vào.
- Cập nhật trạng thái
ModelState
:- Trạng thái xác thực của dữ liệu được cập nhật tự động dựa trên ViewModel.
- Kiểm tra tính hợp lệ của dữ liệu:
- Nếu hợp lệ, dữ liệu sẽ được xử lý (lưu vào cơ sở dữ liệu, gửi API, v.v.).
- Nếu không hợp lệ, hiển thị thông báo lỗi.
- Lưu dữ liệu hợp lệ vào cơ sở dữ liệu.
- Hiển thị phản hồi:
- Hiển thị kết quả hoặc biểu mẫu với lỗi xác thực nếu có.
Bước 2 xảy ra khi dữ liệu trong phương thức View
được ánh xạ tới dữ liệu trong mô hình hoặc ViewModel trong quá trình xử lý liên kết mô hình. Việc hiển thị ViewModel giúp người dùng sửa dữ liệu đầu vào và gửi lại biểu mẫu.
Hình 4.22: Minh họa quy trình xác thực phía server.
Xác thực đầu vào trong biểu mẫu:
- Xác thực phía server (Server-side):
- Quá trình xác thực dữ liệu đầu vào diễn ra tại server sau khi dữ liệu được gửi từ client.
- Cần thiết khi dữ liệu đầu vào phải được kiểm tra bằng tài nguyên của server trước khi xử lý yêu cầu.
- Xác thực phía client (Client-side):
- Diễn ra trên trình duyệt web của người dùng.
- Không yêu cầu gửi dữ liệu về server (không cần postback).
So sánh xác thực client-side và server-side:
- Xác thực phía client:
- Dữ liệu người dùng được kiểm tra ngay tại trình duyệt.
- Không làm chậm quy trình vì không yêu cầu gửi dữ liệu đến server.
- Xác thực phía server:
- Bắt buộc trong các trường hợp dữ liệu đầu vào cần xác thực bảo mật nghiêm ngặt.
- Dữ liệu được xác thực trên server trong quá trình gửi và xử lý lại (postback).