Advanced Cross-Platform Application Programming With .NET - Lập trình ứng dụng đa nền tảng nâng cao với .NET
PRN222 - Lập trình ứng dụng đa nền tảng nâng cao với .NET dạy cách dựng ứng dụng web chạy trên nhiều nền tảng bằng C# 12 và .NET 8 với ASP.NET Core. Môn đi từ chỗ hai tiến trình nói chuyện được với nhau, qua cách làm cho một máy chủ phục vụ nhiều người cùng lúc mà không đứng hình, tới các mô hình dựng giao diện và các dịch vụ chạy ngầm phía sau. Lớp dưới cùng là lập trình mạng trong .NET với địa chỉ IP, hostname, DNS, URI, các giao thức TCP và UDP, TcpListener cùng AcceptSocketAsync, TcpClient, Socket, lớp Stream, HttpClient và GetAsync. Lớp kế là lập trình bất đồng bộ và song song: async/await, Task, Task.Wait, Task.WhenAll, không gian tên System.Threading.Tasks, Parallel.ForEach, Task Parallel Library, PLINQ với AsParallel, cùng ranh giới giữa tác vụ I/O-bound và tác vụ CPU-bound. Phần kiến trúc dựng Dependency Injection và Inversion of Control trên nền nguyên lý SOLID, với AddScoped, AddTransient, AddSingleton và các vòng đời service, constructor injection, property injection, IServiceProvider, Dependency Inversion và Open Closed. Trên nền đó là ba lối dựng giao diện web. ASP.NET Core MVC tách controller, action, IActionResult, ViewResult, HttpPost, Bind, Compare, directive @model, cú pháp Razor, ViewData và ViewBag, PartialView, thư mục wwwroot, model binding và model validation qua ModelState. Razor Pages gộp trang với mã xử lý: file .cshtml, thư mục Pages, lớp PageModel, handler OnGet và OnPost, AddRazorPages, BindProperty, _Layout.cshtml, TempData, Session, Cookies, tiêm phụ thuộc vào PageModel và kiểm tra dữ liệu phía client bằng jQuery Unobtrusive Validation. Blazor đưa C# xuống trình duyệt theo ý niệm C# Everywhere, với Blazor Server, Blazor WebAssembly, hai chế độ render, component, App.razor, directive @page, @bind, @inject, khối @code và thuộc tính Parameter. Hai mảng cuối lo phần chạy ngầm: giao tiếp thời gian thực bằng SignalR với lớp Hub, IHubContext, Clients, Groups.AddToGroupAsync, Hub filters, MessagePack, tự động kết nối lại, AddSignalR, Context và User; cùng Worker Service với BackgroundService, IHostedService, Microsoft.Extensions.Hosting, ExecuteAsync, StartAsync, StopAsync, CancellationToken, cấu hình trong appsettings.json và xử lý hàng đợi. Dữ liệu đi xuyên suốt các lớp đó qua Entity Framework Core và DbContext. Học xong, người học dựng được một ứng dụng .NET nhiều tầng, chọn đúng mô hình giao diện cho từng bài toán và xử lý được phần việc chạy nền lẫn phần đẩy dữ liệu tức thời.
if the model is valid after form submission? public IActionResult OnPost(){if(???){// process data}
return Page();}
AModel.Check()
BModelState.IsValid
CValidateModel()
DModel.IsValid()
Lời giải
Để kiểm tra xem mô hình (model) có hợp lệ sau khi submit form trong một phương thức xử lý Razor Page, bạn cần sử dụng phương thức ModelState.IsValid. Phương thức này sẽ kiểm tra xem tất cả các thuộc tính của mô hình có được nhập đúng hay không, và trả về giá trị boolean (true hoặc false) để chỉ ra mô hình có hợp lệ hay không. Nếu mô hình hợp lệ, bạn có thể thực hiện các hành động cần thiết. Ví dụ:
Lời giải
public IActionResult OnPost(){if(ModelState.IsValid){// Xử lý dữ liệu}
return Page();}
Trong Razor Pages, một trang web được tạo thành từ các phần tử nhỏ hơn được gọi là các trang. Mỗi trang được định nghĩa bởi một lớp riêng biệt. Để định nghĩa một trang, chúng ta sử dụng một số thuộc tính đặc biệt trong Razor. Trong đó, thuộc tính '@page' được sử dụng để định nghĩa mô hình trang. Nó cho phép chúng ta chỉ định tên của trang và các thuộc tính khác mà trang đó có thể sử dụng.
Razor Pages sử dụng thư mục nào làm gốc cho routing mặc định? Khi tạo một ứng dụng Razor Pages mới, .NET Core sẽ tạo ra một số thư mục và file cơ bản. Trong đó, thư mục quan trọng là /Pages. Thư mục này chứa các file Razor Pages, mỗi file tương ứng với một trang web. Khi bạn tạo một file Razor Pages mới, .NET Core sẽ tự động tạo ra một đường dẫn routing cho nó. Đường dẫn này được xác định bởi tên file và tên phương thức trong file đó. Ví dụ, nếu bạn tạo một file Index.cshtml trong thư mục Pages, đường dẫn routing mặc định sẽ là /Pages/Index. Điều này cho phép bạn truy cập trang web dễ dàng thông qua đường dẫn này.
BTo specify the PageModel type for the Razor Page.
CTo encrypt data.
DTo manage user sessions.
Lời giải
Mục đích của chỉ thị @model trong một trang Razor là để chỉ định loại PageModel cho trang Razor. Khi bạn tạo một trang Razor mới, bạn sẽ thấy một file có tên tương tự với tên trang Razor đó, nhưng có phần mở rộng là .cs. Đây là nơi bạn sẽ định nghĩa PageModel cho trang Razor. Chỉ thị @model được sử dụng để chỉ định loại PageModel mà trang Razor sẽ sử dụng. Ví dụ, nếu bạn muốn sử dụng PageModel có tên là MyPageModel, bạn sẽ sử dụng chỉ thị @model như sau: @model MyPageModel. Điều này cho phép bạn sử dụng các thuộc tính và phương thức của PageModel trong trang Razor.
BTo represent a database session and provide methods for querying and saving data.
CTo encrypt data.
DTo render UI components.
Lời giải
DbContext trong một ứng dụng Blazor Web App sử dụng Entity Framework Core là một lớp quan trọng giúp quản lý kết nối cơ sở dữ liệu và cung cấp các phương thức để truy vấn và lưu trữ dữ liệu. Nó đại diện cho một phiên làm việc với cơ sở dữ liệu, cho phép bạn thực hiện các hoạt động như thêm, sửa, xóa và tìm kiếm dữ liệu. DbContext cũng cung cấp các phương thức để quản lý các thay đổi dữ liệu, chẳng hạn như Add, Update và Delete. Ngoài ra, nó còn giúp bạn quản lý các mối quan hệ giữa các bảng trong cơ sở dữ liệu. Tóm lại, DbContext là một lớp quan trọng giúp bạn tương tác với cơ sở dữ liệu một cách hiệu quả và an toàn.
Blazor cung cấp hai chế độ rendering chính là WebAssembly và Server. Chế độ WebAssembly cho phép chạy ứng dụng Blazor trên máy khách (client-side), trong khi chế độ Server cho phép chạy ứng dụng Blazor trên máy chủ (server-side). Chế độ WebAssembly sử dụng công nghệ WebAssembly để biên dịch mã C# thành mã máy tính có thể chạy trên trình duyệt, trong khi chế độ Server sử dụng ASP.NET Core để chạy ứng dụng Blazor trên máy chủ. Mỗi chế độ rendering có ưu và nhược điểm riêng, và người dùng có thể chọn chế độ phù hợp với nhu cầu của mình.
Để thực hiện hai chiều dữ liệu (two-way data binding), chúng ta sử dụng chỉ thị @bind. Chỉ thị này cho phép dữ liệu được cập nhật đồng bộ giữa giao diện người dùng và lớp mẫu (model). Điều này có nghĩa là bất kỳ thay đổi nào được thực hiện trên giao diện người dùng sẽ được phản ánh ngay lập tức trong lớp mẫu, và ngược lại. @bind là một trong những chỉ thị quan trọng nhất trong Angular, giúp tạo ra ứng dụng có tính tương tác cao và dễ sử dụng.
ASP.NET Core Blazor là một công nghệ phát triển ứng dụng web tiên tiến. Một trong những lợi ích chính của nó là khả năng viết logic phía client bằng ngôn ngữ C#. Điều này cho phép các nhà phát triển có thể tận dụng kiến thức và kỹ năng của họ trong C# để xây dựng các ứng dụng web phức tạp mà không cần phải chuyển sang JavaScript. Việc này giúp giảm thiểu thời gian và công sức cần thiết để phát triển ứng dụng, đồng thời cũng giúp đảm bảo chất lượng và tính ổn định của ứng dụng. Ngoài ra, khả năng viết logic phía client bằng C# cũng giúp tăng cường khả năng bảo mật và giảm thiểu rủi ro bảo mật trong ứng dụng.
Trong .NET, lớp được sử dụng để đăng ký dịch vụ cho Dependency Injection là lớp ServiceCollection. Lớp này cung cấp các phương thức để thêm, xóa và kiểm tra các dịch vụ đã được đăng ký. ServiceCollection được sử dụng để quản lý các dịch vụ trong ứng dụng .NET và cung cấp khả năng tùy chỉnh cao để đăng ký các dịch vụ khác nhau. Khi sử dụng Dependency Injection, ServiceCollection được sử dụng để đăng ký các dịch vụ và cung cấp khả năng giải quyết các dịch vụ cho các lớp khác trong ứng dụng.
Đạo lệnh @inject trong Blazor được sử dụng để chèn phụ thuộc vào một thành phần. Điều này có nghĩa là bạn có thể sử dụng các dịch vụ hoặc đối tượng khác trong ứng dụng của mình mà không cần phải tạo ra chúng từ đầu. Ví dụ, nếu bạn có một dịch vụ để lưu trữ dữ liệu, bạn có thể sử dụng @inject để chèn dịch vụ này vào một thành phần của ứng dụng. Điều này giúp giảm thiểu mã nguồn và tăng cường khả năng tái sử dụng. Ngoài ra, @inject cũng giúp bạn dễ dàng thay đổi hoặc cập nhật các phụ thuộc mà không cần phải thay đổi mã nguồn của ứng dụng.
Trong ASP.NET Core MVC, 'Action Result' là một loại kết quả được trả về bởi một hành động. Nó đại diện cho kết quả của một hành động và có thể là một trang web (ViewResult), một chuyển hướng (RedirectResult), một tập tin (FileResult), v.v. ViewResult là một ví dụ về Action Result, nó được sử dụng để trả về một trang web (View) sau khi thực hiện một hành động. ViewResult có thể được sử dụng để trả về một trang web có nội dung được tạo động hoặc một trang web có nội dung được lưu trữ trong tệp.
DData is processed only after user refreshes the page.
Lời giải
Trong bối cảnh ứng dụng web thời gian thực, "thời gian thực" chủ yếu có nghĩa là gì? Đây là một khái niệm quan trọng trong việc xây dựng các ứng dụng web thời gian thực. Nói một cách đơn giản, "thời gian thực" có nghĩa là dữ liệu được cập nhật ngay lập tức và phản hồi từ máy chủ đến khách hàng cũng phải ngay lập tức. Điều này cho phép người dùng nhận được thông tin mới nhất và cập nhật ngay lập tức, mà không cần phải chờ đợi. Ví dụ, khi bạn gửi một tin nhắn trên ứng dụng thời gian thực, bạn sẽ nhận được phản hồi ngay lập tức, chứ không phải sau một khoảng thời gian chờ đợi. Điều này đòi hỏi các ứng dụng web phải có khả năng xử lý và phản hồi nhanh chóng, để đảm bảo trải nghiệm người dùng tốt nhất.
Để bắt đầu kết nối SignalR trên phía client, chúng ta cần sử dụng phương thức start(). Phương thức này được sử dụng để khởi tạo và bắt đầu kết nối với server SignalR. Khi gọi phương thức start(), client sẽ gửi yêu cầu đến server để thiết lập kết nối và bắt đầu truyền thông tin. Phương thức start() là phương thức quan trọng và bắt buộc để bắt đầu sử dụng SignalR trên phía client.
Các câu hỏi về các trung tâm (hubs) trong SignalR như sau:
- Các trung tâm có thể quản lý kết nối của các client.
- Các trung tâm có thể gọi các phương thức trên các client.
- Các trung tâm lưu trữ các tin nhắn có tính bền vững.
- Các trung tâm yêu cầu HTTPS.
Trong đó, hai câu hỏi đúng là:
- Các trung tâm có thể quản lý kết nối của các client.
- Các trung tâm có thể gọi các phương thức trên các client.
Các trung tâm trong SignalR có thể quản lý các kết nối của các client và gọi các phương thức trên các client để thực hiện các tác vụ khác nhau.
BTo act as a high-level pipeline allowing clients and servers to call methods on each other.
CTo send HTTP requests only from server to client.
DTo replace all API controllers in ASP.NET Core.
Lời giải
Một SignalR hub là một lớp trung gian cao cấp cho phép các khách hàng và máy chủ gọi các phương thức vào nhau. Nó cho phép các ứng dụng thực hiện giao tiếp hai chiều giữa máy chủ và khách hàng, cho phép các máy chủ gửi thông tin đến các khách hàng và ngược lại. Điều này giúp tạo ra các ứng dụng thời gian thực, chẳng hạn như trò chơi trực tuyến, ứng dụng thời gian thực và các ứng dụng khác yêu cầu giao tiếp đồng bộ giữa máy chủ và khách hàng.
Để thêm dịch vụ SignalR vào bộ chứa DI (Dependency Injection), bạn cần sử dụng phương thức AddSignalR(). Phương thức này cho phép bạn cấu hình và thêm dịch vụ SignalR vào ứng dụng ASP.NET Core của mình. Khi sử dụng AddSignalR(), bạn có thể cấu hình các tùy chọn như loại giao thức, số lượng kết nối và các tùy chọn khác để phù hợp với nhu cầu của ứng dụng. Ngoài ra, bạn cũng có thể sử dụng AddSignalR() để thêm dịch vụ SignalR vào ứng dụng ASP.NET Core trong môi trường phát triển hoặc sản xuất.
MessagePack là một định dạng serialize binary được sử dụng để chuyển đổi dữ liệu giữa các ngôn ngữ lập trình khác nhau. Nó được thiết kế để có kích thước nhỏ và tốc độ nhanh chóng, giúp giảm thiểu thời gian truyền dữ liệu qua mạng. MessagePack được sử dụng rộng rãi trong các ứng dụng cần truyền tải dữ liệu nhanh chóng và hiệu quả, chẳng hạn như SignalR, một thư viện truyền thông thực thời gian cho ASP.NET. Nó cũng được sử dụng trong các ứng dụng khác như Node.js và Python. MessagePack có thể serialize các dữ liệu phức tạp như mảng, đối tượng và chuỗi, giúp giảm thiểu thời gian truyền dữ liệu và tăng hiệu suất ứng dụng.
SignalR là một thư viện cho ASP.NET Core cho phép tạo ứng dụng thời gian thực. Một trong những tính năng quan trọng của SignalR là khả năng tự động quản lý kết nối lại. Điều này có nghĩa là nếu kết nối bị mất do lỗi mạng hoặc do người dùng đóng trang, SignalR sẽ tự động cố gắng kết nối lại mà không cần người dùng phải thực hiện bất kỳ hành động nào. Tính năng này giúp đảm bảo rằng ứng dụng thời gian thực luôn hoạt động ổn định và không bị gián đoạn. Ngoài ra, SignalR cũng hỗ trợ các tính năng khác như gửi tin nhắn thời gian thực, cập nhật trạng thái thời gian thực, v.v.
Blazor Server sử dụng SignalR để cập nhật giao diện người dùng. SignalR là một thư viện ASP.NET cho phép thực hiện giao tiếp thực thời gian giữa client và server. Khi bạn sử dụng Blazor Server, giao diện người dùng được cập nhật thông qua SignalR. Điều này cho phép giao diện người dùng được cập nhật ngay lập tức mà không cần phải tải lại trang web. SignalR sử dụng các kết nối WebSocket để thực hiện giao tiếp thực thời gian giữa client và server.
public class EmailWorker : BackgroundService {
protected override async Task ExecuteAsync(CancellationToken stoppingToken){while(!stoppingToken.IsCancellationRequested){SendEmails();
await Task.Delay(60000, stoppingToken);}}}
What does this service do?
ASends emails every minute.
BSends emails once.
CLogs emails only.
DIgnores shutdown signals.
Lời giải
Dịch vụ EmailWorker được triển khai dựa trên lớp BackgroundService trong C#. Lớp này thực hiện việc gửi email một cách lặp đi lặp lại. Trong phương thức ExecuteAsync, dịch vụ này sẽ tiếp tục gửi email cho đến khi nhận được tín hiệu hủy bỏ. Trong mỗi vòng lặp, dịch vụ sẽ gọi phương thức SendEmails để gửi email và sau đó chờ 1 phút trước khi tiếp tục. Điều này cho thấy dịch vụ sẽ gửi email mỗi phút một lần.