PRN222DễKỳ 7Chuyên ngành Cập nhật 07/09/2026

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.

175Câu hỏi
4Bộ đề
8Chủ đề
5,01 đánh giá

Câu hỏi của môn

44/175 câuCòn 131
ATcpClient
BUdpClient
CTcpListener
DSocket
Lời giải
Để lắng nghe các kết nối TCP vào một cổng cụ thể, bạn cần sử dụng lớp .NET TcpListener. TcpListener cho phép bạn tạo một máy chủ TCP và lắng nghe các yêu cầu kết nối từ các máy khách. Khi một máy khách kết nối đến máy chủ, bạn có thể sử dụng phương thức Accept để chấp nhận kết nối và bắt đầu giao tiếp với máy khách. TcpListener cũng cung cấp các phương thức để gửi và nhận dữ liệu qua TCP, giúp bạn xây dựng các ứng dụng mạng phức tạp. Ngoài ra, TcpListener cũng hỗ trợ các tính năng như xác thực và mã hóa để đảm bảo an toàn cho các giao tiếp mạng.
Mở trang câu hỏi này →
26Consider this C# code:4 lựa chọncó codeTrung bình67% trả lời đúng
Đề bài
public IActionResult Save(Person person) {
  if (ModelState.IsValid) return Content("Valid");
  return Content("Error");
}

If no value for Age is passed and Age is int, what happens?

AValid
BError
CException
DNull
Lời giải
Nếu không có giá trị cho thuộc tính Age và Age được định nghĩa là kiểu int, thì khi thực hiện phương thức Save, chương trình sẽ không ném ra ngoại lệ. Thay vào đó, nó sẽ kiểm tra trạng thái hợp lệ của mô hình (ModelState.IsValid). Vì Age không được cung cấp, nên mô hình sẽ không hợp lệ. Do đó, phương thức sẽ trả về nội dung "Error".
Mở trang câu hỏi này →
27Consider this C# code:4 lựa chọncó codeDễ80% trả lời đúng
Đề bài
public class Person {
  public int Age { get; set; }
}
public IActionResult Save(Person person) {
  if (!ModelState.IsValid) {
    return Content("Invalid!");
  }
  return Content("OK");
}

Input: Age = "abc"? What is the output?

AOK
BInvalid!
CException
DNull
Lời giải
Khi thực hiện việc lưu trữ thông tin người dùng với lớp Person, chúng ta cần kiểm tra xem dữ liệu đầu vào có hợp lệ hay không. Trong trường hợp này, lớp Person chỉ có một thuộc tính là Age, và dữ liệu đầu vào là một chuỗi 'abc'. Vì Age được định nghĩa là một số nguyên (int), nên khi chúng ta cố gắng lưu trữ chuỗi 'abc' vào thuộc tính Age, hệ thống sẽ phát hiện ra lỗi và trả về thông điệp 'Invalid!' để thông báo cho người dùng.
Mở trang câu hỏi này →
28Which directive is used to declare a strongly-typed View?4 lựa chọnTrung bình43% trả lời đúng
A@model
B@view
C@bind
D@data
Lời giải
Để tạo một View được định nghĩa rõ ràng (strongly-typed View), bạn cần sử dụng một trong các chỉ thị sau. Trong đó, chỉ thị '@model' được sử dụng rộng rãi nhất để khai báo kiểu dữ liệu của View. Ví dụ, nếu bạn muốn tạo một View để hiển thị thông tin về một người dùng, bạn có thể sử dụng '@model' để khai báo kiểu dữ liệu là 'User'. Điều này giúp cho View của bạn được định nghĩa rõ ràng và dễ dàng sử dụng.
Mở trang câu hỏi này →
29Consider this C# code:4 lựa chọncó codeDễ75% trả lời đúng
Đề bài
public IActionResult Index() {
  ViewData["User"] = "Admin";
  return View();
}

Razor: <p>@ViewBag.User</p> What is displayed?

AAdmin
Bnull
CError
DNothing
Lời giải
Khi chạy mã C# trên, chúng ta sẽ thấy kết quả là "Admin". Lý do là vì trong phương thức Index(), chúng ta đã gán giá trị "Admin" vào ViewData với khóa "User". Sau đó, trong Razor, chúng ta sử dụng ViewBag.User để hiển thị giá trị này. Vì vậy, kết quả cuối cùng sẽ là "Admin".
Mở trang câu hỏi này →
30What does the IActionResult interface represent?4 lựa chọnDễ100% trả lời đúng
AA database connection.
BThe result of an action method.
CA user session.
DA network request.
Lời giải
IActionResult là một giao diện trong ASP.NET Core, đại diện cho kết quả của một phương thức hành động. Nó cho phép bạn trả về nhiều loại kết quả khác nhau, chẳng hạn như một trang web, một chuyển hướng, một trạng thái HTTP, v.v. Khi một phương thức hành động được gọi, nó sẽ trả về một đối tượng thực thi IActionResult, đại diện cho kết quả của phương thức đó. Điều này cho phép bạn xử lý kết quả một cách linh hoạt và dễ dàng trong ứng dụng của mình.
Mở trang câu hỏi này →
31What is "Model Validation" in ASP.NET Core MVC?4 lựa chọnDễ100% trả lời đúng
AThe process of encrypting data.
BThe process of ensuring that user input meets specific criteria.
CThe process of managing database connections.
DThe process of routing HTTP requests.
Lời giải
Trong ASP.NET Core MVC, "Model Validation" là quá trình đảm bảo rằng dữ liệu được nhập vào bởi người dùng đáp ứng các tiêu chí cụ thể. Quá trình này giúp ngăn chặn các dữ liệu không hợp lệ được lưu trữ vào cơ sở dữ liệu hoặc sử dụng trong ứng dụng. Model Validation thường được thực hiện bằng cách sử dụng các thuộc tính và phương thức đặc biệt trên mô hình dữ liệu (model) để xác minh tính hợp lệ của dữ liệu. Ví dụ, bạn có thể sử dụng thuộc tính `[Required]` để yêu cầu một trường dữ liệu không được bỏ trống, hoặc thuộc tính `[Range]` để xác định phạm vi giá trị cho một trường dữ liệu. Quá trình này giúp đảm bảo rằng dữ liệu được nhập vào là chính xác và đáng tin cậy, từ đó giúp ứng dụng hoạt động ổn định và hiệu quả.
Mở trang câu hỏi này →
32How do you inject a service into a Razor PageModel?4 lựa chọnDễ100% trả lời đúng
ABy directly creating an instance of the service.
BBy adding the service as a constructor parameter.
CBy using global variables.
DBy using static methods.
Lời giải

Để chèn một dịch vụ vào một Razor PageModel, bạn cần sử dụng một trong các phương pháp sau. Phương pháp chính xác là thêm dịch vụ vào tham số constructor. Điều này cho phép bạn sử dụng dịch vụ trong các phương thức của PageModel. Ví dụ, bạn có thể thêm dịch vụ vào constructor như sau:

Lời giải
public class MyPageModel : PageModel {
 private readonly MyService _myService;
 public MyPageModel(MyService myService)
 {
 _myService = myService;
 }
 public void OnGet()
 {
 _myService.DoSomething();
 }
 }

Sau đó, bạn cần thêm dịch vụ vào DI container trong Startup.cs.

Lời giải
services.AddTransient<MyService>();

Điều này cho phép bạn sử dụng dịch vụ trong PageModel.

Mở trang câu hỏi này →
33What is the file extension for Razor Page files?4 lựa chọnDễ80% trả lời đúng
A.cshtml
B.razor
C.aspx
D.html
Lời giải
Câu hỏi này yêu cầu bạn chọn file extension phù hợp cho các file Razor Page. Razor Page là một loại file trong ASP.NET Core, được sử dụng để tạo các trang web động. Câu trả lời đúng là .cshtml, vì nó là file extension tiêu chuẩn cho các file Razor Page. Các file .cshtml chứa mã C# và HTML, giúp tạo ra các trang web động phức tạp. Các file .razor cũng có thể được sử dụng, nhưng nó không phải là file extension mặc định. Các file .aspx và .html không phù hợp cho các file Razor Page.
Mở trang câu hỏi này →
34How is dependency injection typically used in Razor Pages?4 lựa chọnDễ100% trả lời đúng
ABy directly creating instances of dependencies.
BBy injecting dependencies into the PageModel constructor.
CBy using global variables.
DBy using static methods.
Lời giải
Tùy thuộc vào Razor Pages, Dependency Injection thường được sử dụng bằng cách chèn các phụ thuộc vào constructor của PageModel. Điều này cho phép bạn tách biệt logic kinh doanh khỏi logic trang web, giúp dễ dàng bảo trì và mở rộng ứng dụng. Khi bạn sử dụng Dependency Injection, bạn có thể dễ dàng thay thế các phụ thuộc bằng các phiên bản mới hoặc các phiên bản khác mà không cần thay đổi mã nguồn của trang web. Điều này giúp tăng cường tính linh hoạt và khả năng mở rộng của ứng dụng.
Mở trang câu hỏi này →
35ViewData in Razor Pages is:4 lựa chọnDễ100% trả lời đúng
AA list of HTML helpers
BA dictionary for passing data from PageModel to Razor Page
CA type of middleware
DA static variable shared by all pages
Lời giải
Trong Razor Pages, ViewData là một đối tượng được sử dụng để truyền dữ liệu từ PageModel sang Razor Page. Nó được định nghĩa là một dictionary, cho phép bạn lưu trữ và truy xuất dữ liệu một cách dễ dàng. Khi bạn muốn truyền dữ liệu từ PageModel sang Razor Page, bạn có thể sử dụng ViewData để lưu trữ dữ liệu và sau đó truy xuất nó trong Razor Page. Điều này giúp bạn có thể chia sẻ dữ liệu giữa các phần của ứng dụng một cách dễ dàng. Ví dụ, bạn có thể sử dụng ViewData để lưu trữ dữ liệu người dùng và sau đó sử dụng nó để hiển thị thông tin người dùng trên Razor Page.
Mở trang câu hỏi này →
36What is the purpose of the [BindProperty] attribute in Razor Pages?4 lựa chọnDễ100% trả lời đúng
ATo define a database connection.
BTo bind form data to a PageModel property.
CTo encrypt data.
DTo manage user sessions.
Lời giải
Trong Razor Pages, [BindProperty] là một thuộc tính quan trọng giúp liên kết dữ liệu từ form với các thuộc tính của PageModel. Khi bạn sử dụng [BindProperty] trên một thuộc tính của PageModel, bạn có thể tự động liên kết dữ liệu từ form với thuộc tính đó. Điều này giúp giảm thiểu mã code và tăng hiệu suất khi xử lý dữ liệu từ form. Ví dụ, nếu bạn có một form với trường nhập tên và địa chỉ, bạn có thể sử dụng [BindProperty] để liên kết dữ liệu từ form với các thuộc tính tên và địa chỉ của PageModel. Điều này giúp bạn dễ dàng truy cập và xử lý dữ liệu từ form trong code-behind của trang Razor Pages.
Mở trang câu hỏi này →
37In Razor Pages, client-side validation is enabled by:4 lựa chọnTrung bình67% trả lời đúng
AASP.NET pipeline
BjQuery Unobtrusive Validation
CSignalR
DAJAX by default
Lời giải
Trong Razor Pages, xác thực ở phía khách hàng được kích hoạt bằng cách sử dụng jQuery Unobtrusive Validation. Điều này cho phép thực hiện xác thực trên trình duyệt mà không cần phải gửi yêu cầu đến máy chủ. Để sử dụng tính năng này, bạn cần thêm thư viện jQuery Unobtrusive Validation vào dự án của mình. Sau đó, bạn có thể sử dụng các thuộc tính dữ liệu (data attributes) để chỉ định các quy tắc xác thực cho các trường nhập liệu. Khi người dùng nhập dữ liệu vào các trường này, trình duyệt sẽ tự động thực hiện xác thực và hiển thị thông báo lỗi nếu dữ liệu không hợp lệ. Điều này giúp cải thiện trải nghiệm người dùng và giảm tải cho máy chủ.
Mở trang câu hỏi này →
38Which principle is emphasized by DI in Razor Pages?4 lựa chọnTrung bình57% trả lời đúng
ADon't Repeat Yourself (DRY)
BMaximum Reuse
CProcedural Programming
DLoose Session Coupling
Lời giải
DI (Dependency Injection) trong Razor Pages nhấn mạnh nguyên tắc không lặp lại (Don't Repeat Yourself, DRY). Nguyên tắc này cho phép giảm thiểu sự lặp lại mã nguồn và tăng cường khả năng tái sử dụng. DI giúp bạn tách biệt các phụ thuộc và cung cấp chúng một cách linh hoạt, từ đó giảm thiểu sự lặp lại mã nguồn và tăng cường tính linh hoạt của ứng dụng. Điều này giúp bạn dễ dàng thay đổi hoặc cập nhật các phụ thuộc mà không ảnh hưởng đến các phần khác của ứng dụng.
Mở trang câu hỏi này →
39What is the typical use case for a Worker Service?4 lựa chọnDễ100% trả lời đúng
AHandling real-time user interactions.
BPerforming scheduled tasks or background processing.
CRendering web pages.
DManaging user authentication.
Lời giải
Một Worker Service là một loại ứng dụng trong hệ thống phân tán, được thiết kế để thực hiện các tác vụ nền hoặc xử lý dữ liệu trong nền. Nó thường được sử dụng để thực hiện các nhiệm vụ lặp đi lặp lại, như gửi email hàng ngày, cập nhật dữ liệu trên cơ sở dữ liệu, hoặc thực hiện các tác vụ khác mà không cần tương tác trực tiếp với người dùng. Trong trường hợp này, câu trả lời đúng là "Thực hiện các tác vụ lặp đi lặp lại hoặc xử lý dữ liệu trong nền".
Mở trang câu hỏi này →
40How do you implement a background task using a Worker Service?4 lựa chọnDễ75% trả lời đúng
ABy writing JavaScript functions.
BBy overriding the ExecuteAsync(CancellationToken) method in a class derived from BackgroundService.
CBy using static HTML files.
DBy using database queries.
Lời giải
Để thực hiện một nhiệm vụ nền (background task) bằng cách sử dụng dịch vụ Worker, bạn cần tạo một lớp kế thừa từ BackgroundService. Lớp này sẽ chứa phương thức ExecuteAsync, nơi bạn thực hiện logic của nhiệm vụ nền. Phương thức này sẽ được gọi tự động bởi dịch vụ Worker khi nó được khởi tạo. Bạn cũng có thể sử dụng phương thức StartAsync để bắt đầu nhiệm vụ nền ngay lập tức. Ngoài ra, bạn có thể sử dụng các thuộc tính và phương thức khác của lớp BackgroundService để quản lý và giám sát nhiệm vụ nền.
Mở trang câu hỏi này →
ATo manage database transactions.
BTo allow the service to be gracefully stopped.
CTo encrypt data.
DTo manage user sessions.
Lời giải
CancellationToken là một tham số quan trọng trong phương thức ExecuteAsync(CancellationToken) trong lập trình. Mục đích chính của tham số này là cho phép dịch vụ được dừng một cách êm ái (gracefully stopped) khi cần thiết. Điều này có nghĩa là khi dịch vụ cần được dừng lại, tham số CancellationToken sẽ được đặt thành trạng thái đã hủy (canceled), từ đó cho phép dịch vụ thực hiện các hành động cần thiết để dừng lại một cách an toàn và không gây ra lỗi. Ví dụ, dịch vụ có thể thoát khỏi các nguồn hệ thống, đóng các kết nối mạng, hoặc thực hiện các hành động khác cần thiết để dừng lại một cách êm ái. Mục đích của CancellationToken là đảm bảo rằng dịch vụ được dừng lại một cách an toàn và không gây ra lỗi khi cần thiết.
Mở trang câu hỏi này →
42Consider this C# code:4 lựa chọncó codeDễ100% trả lời đúng
Đề bài
public class Worker : BackgroundService {
  protected override Task ExecuteAsync(CancellationToken stoppingToken) {
    return Task.CompletedTask;
  }
}

What is ExecuteAsync?

AThe entry point for background execution.
BThe constructor.
CA logging method.
DA thread initializer.
Lời giải
Trong mã nguồn C#, ExecuteAsync là phương thức được sử dụng để thực hiện các tác vụ nền (background tasks). Nó là phương thức được gọi khi một đối tượng thực hiện các tác vụ nền (background service) được tạo ra. Phương thức này được sử dụng để thực hiện các tác vụ nền một cách độc lập và không ảnh hưởng đến luồng chính của chương trình. Trong ví dụ trên, Worker là một lớp thực hiện các tác vụ nền và ExecuteAsync là phương thức được sử dụng để thực hiện các tác vụ nền này. Phương thức ExecuteAsync được gọi khi Worker được tạo ra và nó sẽ thực hiện các tác vụ nền một cách độc lập.
Mở trang câu hỏi này →
43Which scenarios are most suitable for Worker Services?4 lựa chọnDễ100% trả lời đúng
AProcessing queue messages
BRunning Blazor UI
CDisplaying Razor Pages
DHosting REST APIs only
Lời giải
Các kịch bản phù hợp nhất cho Worker Services là các trường hợp xử lý hàng đợi (queue messages). Worker Services được thiết kế để chạy trong nền và xử lý các tác vụ lặp đi lặp lại, chẳng hạn như xử lý hàng đợi. Điều này giúp giảm tải cho ứng dụng web và cải thiện hiệu suất. Ngoài ra, Worker Services cũng có thể được sử dụng để chạy các tác vụ độc lập, chẳng hạn như gửi email hoặc thông báo. Tuy nhiên, các kịch bản như chạy UI Blazor, hiển thị Razor Pages hoặc chỉ hosting REST APIs không phù hợp với Worker Services vì chúng yêu cầu tương tác trực tiếp với người dùng hoặc yêu cầu hiển thị UI.
Mở trang câu hỏi này →
ATo handle HTTP requests.
BTo define the main logic of the background task.
CTo manage database connections.
DTo define user interfaces.
Lời giải
Phương thức ExecuteAsync(CancellationToken) trong lớp BackgroundService có vai trò quan trọng trong việc định nghĩa logic chính của nhiệm vụ chạy nền. Phương thức này được gọi khi BackgroundService được khởi tạo và sẽ chạy liên tục cho đến khi ứng dụng bị dừng. Trong phương thức này, bạn có thể thực hiện các tác vụ như đọc dữ liệu từ cơ sở dữ liệu, xử lý dữ liệu, gửi thông báo, v.v. Mục đích chính của phương thức này là thực hiện các tác vụ nền mà không ảnh hưởng đến giao diện người dùng. Ví dụ, bạn có thể sử dụng phương thức này để gửi thông báo hàng ngày hoặc hàng giờ, hoặc để cập nhật dữ liệu trên cơ sở dữ liệu.
Mở trang câu hỏi này →