Nguon: Microsoft Learn · .NET 8.0
Tạo Web API với ASP.NET Core và MongoDB
Hướng dẫn toàn diện này hướng dẫn tạo web API thực hiện các thao tác CRUD (Create, Read, Update, Delete - Tạo, Đọc, Cập nhật, Xóa) trên cơ sở dữ liệu NoSQL MongoDB sử dụng ASP.NET Core.
Tổng quan
Hướng dẫn dạy cách:
- Cấu hình MongoDB
- Tạo cơ sở dữ liệu MongoDB
- Định nghĩa collection và schema MongoDB
- Thực hiện các thao tác CRUD MongoDB từ web API
- Tùy chỉnh JSON serialization (tuần tự hóa JSON)
Yêu cầu tiên quyết
Yêu cầu cốt lõi
- MongoDB 8.0.0 trở lên (cho .NET 10/11) hoặc MongoDB 6.0.5 trở lên (cho các phiên bản trước)
- MongoDB Shell
Công cụ phát triển
Visual Studio:
- Phiên bản mới nhất của Visual Studio với workload ASP.NET and web development
Visual Studio Code:
- Visual Studio Code
- C# Dev Kit cho Visual Studio Code
- .NET 10.0 SDK (hoặc phiên bản phù hợp với phiên bản ASP.NET Core của bạn)
Các bước cấu hình MongoDB
- Cài đặt MongoDB Shell
- macOS/Linux: Giải nén và thêm
mongoshvào PATH - Windows: Đã có tại C:\Users\{USER}\AppData\Local\Programs\mongosh
- Cài đặt MongoDB
- macOS/Linux: Thường tại /usr/local/mongodb
- Windows: Vị trí mặc định C:\Program Files\MongoDB
- Tạo thư mục dữ liệu
- macOS/Linux:
/usr/local/var/mongodb - Windows:
C:\BooksData - Khởi động server MongoDB
console
mongod --dbpath {ĐƯỜNG DẪN THƯ MỤC DỮ LIỆU}Thiết lập cơ sở dữ liệu
Kết nối với MongoDB Shell
console
mongosh
Tạo cơ sở dữ liệu và collection
console
use BookStore
db.createCollection('Books')Chèn dữ liệu mẫu
console
db.Books.insertMany([
{
"Name": "Design Patterns",
"Price": 54.93,
"Category": "Computers",
"Author": "Ralph Johnson"
},
{
"Name": "Clean Code",
"Price": 43.15,
"Category": "Computers",
"Author": "Robert C. Martin"
}
])Xác minh dữ liệu
console
db.Books.find().pretty()
Thiết lập dự án
Tạo dự án ASP.NET Core Web API
Visual Studio:
- File > New > Project (Tệp > Mới > Dự án)
- Chọn ASP.NET Core Web API
- Tên: BookStoreApi
- Framework: .NET 10.0 (hoặc phiên bản phù hợp)
- Bỏ chọn "Use controllers" cho .NET 10/11 (minimal APIs)
- Chọn "Enable OpenAPI support" (Bật hỗ trợ OpenAPI)
Visual Studio Code:
dotnetcli
dotnet new webapi -o BookStoreApi code BookStoreApi
Cài đặt MongoDB Driver (trình điều khiển MongoDB)
powershell
Install-Package MongoDB.Driver
Hoặc với .NET CLI:
dotnetcli
dotnet add package MongoDB.Driver
Model thực thể
Tạo Models/Book.cs:
csharp
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using System.Text.Json.Serialization;
namespace BookStoreApi.Models;
public class Book
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string? Id { get; set; }
[BsonElement("Name")]
[JsonPropertyName("Name")]
public string BookName { get; set; } = null!;
public decimal Price { get; set; }
public string Category { get; set; } = null!;
public string Author { get; set; } = null!;
}Các thuộc tính quan trọng:
[BsonId]: Đánh dấu là khóa chính[BsonRepresentation(BsonType.ObjectId)]: Cho phép chuyển đổi tham số string[BsonElement("Name")]: Ánh xạ đến trường MongoDB[JsonPropertyName("Name")]: Tên khi serialize JSON
Cấu hình cơ sở dữ liệu
Cập nhật appsettings.json
json
{
"BookStoreDatabase": {
"ConnectionString": "mongodb://localhost:27017",
"DatabaseName": "BookStore",
"BooksCollectionName": "Books"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}Tạo Model cấu hình
Models/BookStoreDatabaseSettings.cs:
csharp
namespace BookStoreApi.Models;
public class BookStoreDatabaseSettings
{
public string ConnectionString { get; set; } = null!;
public string DatabaseName { get; set; } = null!;
public string BooksCollectionName { get; set; } = null!;
}Đăng ký cấu hình trong Program.cs
csharp
using BookStoreApi.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.Configure<BookStoreDatabaseSettings>(
builder.Configuration.GetSection("BookStoreDatabase"));Service CRUD (dịch vụ CRUD)
Tạo Services/BooksService.cs:
csharp
using BookStoreApi.Models;
using Microsoft.Extensions.Options;
using MongoDB.Driver;
namespace BookStoreApi.Services;
public class BooksService(IOptions<BookStoreDatabaseSettings> bookStoreDatabaseSettings)
{
private readonly IMongoCollection<Book> _booksCollection =
new MongoClient(bookStoreDatabaseSettings.Value.ConnectionString)
.GetDatabase(bookStoreDatabaseSettings.Value.DatabaseName)
.GetCollection<Book>(bookStoreDatabaseSettings.Value.BooksCollectionName);
public async Task<List<Book>> GetAsync() =>
await _booksCollection.Find(_ => true).ToListAsync();
public async Task<Book?> GetAsync(string id) =>
await _booksCollection.Find(x => x.Id == id).FirstOrDefaultAsync();
public async Task CreateAsync(Book newBook) =>
await _booksCollection.InsertOneAsync(newBook);
public async Task UpdateAsync(string id, Book updatedBook) =>
await _booksCollection.ReplaceOneAsync(x => x.Id == id, updatedBook);
public async Task RemoveAsync(string id) =>
await _booksCollection.DeleteOneAsync(x => x.Id == id);
}Đăng ký Service trong Program.cs
csharp
using BookStoreApi.Services; builder.Services.AddSingleton<BooksService>();
Các Endpoint API (Minimal APIs - .NET 10/11)
Thêm vào Program.cs:
csharp
var booksGroup = app.MapGroup("/books");
booksGroup.MapGet("/", async (BooksService booksService) =>
{
var books = await booksService.GetAsync();
return Results.Ok(books);
});
booksGroup.MapGet("/{id:length(24)}", async (string id, BooksService booksService) =>
{
var book = await booksService.GetAsync(id);
return book is null ? Results.NotFound() : Results.Ok(book);
});
booksGroup.MapPost("/", async (Book newBook, BooksService booksService) =>
{
await booksService.CreateAsync(newBook);
return Results.Created($"/books/{newBook.Id}", newBook);
});
booksGroup.MapPut("/{id:length(24)}", async (string id, Book updatedBook, BooksService booksService) =>
{
var book = await booksService.GetAsync(id);
if (book is null) return Results.NotFound();
updatedBook.Id = book.Id;
await booksService.UpdateAsync(id, updatedBook);
return Results.NoContent();
});
booksGroup.MapDelete("/{id:length(24)}", async (string id, BooksService booksService) =>
{
var book = await booksService.GetAsync(id);
if (book is null) return Results.NotFound();
await booksService.RemoveAsync(id);
return Results.NoContent();
});Các Endpoint API (dựa trên Controller - phiên bản trước)
Tạo Controllers/BooksController.cs:
csharp
using BookStoreApi.Models;
using BookStoreApi.Services;
using Microsoft.AspNetCore.Mvc;
namespace BookStoreApi.Controllers;
[ApiController]
[Route("api/[controller]")]
public class BooksController : ControllerBase
{
private readonly BooksService _booksService;
public BooksController(BooksService booksService) =>
_booksService = booksService;
[HttpGet]
public async Task<List<Book>> Get() =>
await _booksService.GetAsync();
[HttpGet("{id:length(24)}")]
public async Task<ActionResult<Book>> Get(string id)
{
var book = await _booksService.GetAsync(id);
return book is null ? NotFound() : book;
}
[HttpPost]
public async Task<IActionResult> Post(Book newBook)
{
await _booksService.CreateAsync(newBook);
return CreatedAtAction(nameof(Get), new { id = newBook.Id }, newBook);
}
[HttpPut("{id:length(24)}")]
public async Task<IActionResult> Update(string id, Book updatedBook)
{
var book = await _booksService.GetAsync(id);
if (book is null) return NotFound();
updatedBook.Id = book.Id;
await _booksService.UpdateAsync(id, updatedBook);
return NoContent();
}
[HttpDelete("{id:length(24)}")]
public async Task<IActionResult> Delete(string id)
{
var book = await _booksService.GetAsync(id);
if (book is null) return NotFound();
await _booksService.RemoveAsync(id);
return NoContent();
}
}Cấu hình JSON Serialization
Minimal APIs (.NET 10/11)
csharp
builder.Services.Configure<Microsoft.AspNetCore.Http.Json.JsonOptions>(options =>
{
options.SerializerOptions.PropertyNamingPolicy = null;
});Controller-based APIs
csharp
builder.Services.AddControllers()
.AddJsonOptions(options =>
options.JsonSerializerOptions.PropertyNamingPolicy = null);Cấu hình này đảm bảo tên thuộc tính giữ nguyên dạng PascalCase thay vì camelCase.
Kiểm thử API
Visual Studio
Dùng Endpoints Explorer với file .http để kiểm thử
Visual Studio Code
- Cài đặt Swagger UI:
dotnetcli
dotnet add package NSwag.AspNetCore
- Cấu hình middleware trong
Program.cs:
csharp
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
app.UseSwaggerUi(options =>
{
options.DocumentPath = "/openapi/v1.json";
});
}- Truy cập
https://localhost:{PORT}/swagger
Ví dụ Response API
json
[
{
"Id": "61a6058e6c43f32854e51f51",
"Name": "Design Patterns",
"Price": 54.93,
"Category": "Computers",
"Author": "Ralph Johnson"
},
{
"Id": "61a6058e6c43f32854e51f52",
"Name": "Clean Code",
"Price": 43.15,
"Category": "Computers",
"Author": "Robert C. Martin"
}
]Xác thực
Để bảo mật API, Microsoft khuyến nghị:
- Microsoft Entra ID cho các kịch bản doanh nghiệp
- Duende Identity Server cho OAuth 2.0 / OpenID Connect
Lưu ý: Duende Software có thể yêu cầu cấp phép cho môi trường production.