Bắt đầu với Swashbuckle và ASP.NET Core
Lưu ý: Trong .NET 9 trở lên, ASP.NET Core đã tích hợp hỗ trợ OpenAPI (OpenAPI support) sẵn có. Swashbuckle không còn được đưa vào mặc định, nhưng vẫn có thể sử dụng dưới dạng community package thêm vào thủ công cho các dự án ASP.NET Core nhắm đến .NET 9 trở lên.
- Để hiểu về các tính năng OpenAPI tích hợp sẵn, xem Tổng quan hỗ trợ OpenAPI trong ứng dụng ASP.NET Core API.
- Để thêm và sử dụng Swagger UI do package Swashbuckle.AspNetCore.SwaggerUI cung cấp, xem Sử dụng tài liệu OpenAPI đã tạo.
Các hướng dẫn sau đây áp dụng khi sử dụng Swashbuckle với .NET phiên bản cũ hơn 9.
Swashbuckle có ba thành phần chính:
- Swashbuckle.AspNetCore.Swagger: một object model Swagger và middleware để expose các đối tượng
SwaggerDocumentdưới dạng JSON endpoint. - Swashbuckle.AspNetCore.SwaggerGen: một Swagger generator (bộ tạo Swagger) xây dựng các đối tượng
SwaggerDocumenttrực tiếp từ các route, controller và model. Nó thường được kết hợp với middleware Swagger endpoint để tự động expose Swagger JSON. - Swashbuckle.AspNetCore.SwaggerUI: phiên bản nhúng (embedded version) của công cụ Swagger UI. Nó diễn giải Swagger JSON để tạo ra trải nghiệm phong phú, có thể tùy chỉnh để mô tả chức năng của web API. Nó bao gồm các test harness (bộ kiểm thử) tích hợp sẵn cho các phương thức công khai.
Cài đặt package
Swashbuckle có thể được thêm vào theo các cách sau:
Visual Studio
- Từ cửa sổ Package Manager Console:
- Vào View > Other Windows > Package Manager Console
- Điều hướng đến thư mục chứa file
.csproj - Thực thi lệnh sau:
``powershell Install-Package Swashbuckle.AspNetCore -Version 6.6.2 ``
- Từ hộp thoại Manage NuGet Packages:
- Nhấp chuột phải vào dự án trong Solution Explorer > Manage NuGet Packages
- Đặt Package source thành "nuget.org"
- Đảm bảo tùy chọn "Include prerelease" được bật
- Nhập "Swashbuckle.AspNetCore" vào ô tìm kiếm
- Chọn package "Swashbuckle.AspNetCore" mới nhất từ tab Browse và nhấp Install
Visual Studio Code
Chạy lệnh sau từ Integrated Terminal:
dotnet add TodoApi.csproj package Swashbuckle.AspNetCore -v 6.6.2
.NET CLI
Chạy lệnh sau:
dotnet add TodoApi.csproj package Swashbuckle.AspNetCore -v 6.6.2
Thêm và cấu hình Swagger middleware
Thêm Swagger generator vào service collection trong Program.cs:
builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen();
Lời gọi AddEndpointsApiExplorer trong ví dụ trên chỉ cần thiết cho Minimal APIs. Để biết thêm thông tin, xem bài đăng StackOverflow này.
Kích hoạt middleware để phục vụ tài liệu JSON đã tạo và Swagger UI, cũng trong Program.cs:
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}Đoạn code trên chỉ thêm Swagger middleware khi môi trường hiện tại được đặt thành Development. Lời gọi phương thức UseSwaggerUI kích hoạt phiên bản nhúng của công cụ Swagger UI.
Khởi động ứng dụng và điều hướng đến https://localhost:<port>/swagger/v1/swagger.json. Tài liệu đã tạo mô tả các endpoint sẽ xuất hiện như được hiển thị trong OpenAPI specification (openapi.json).
Swagger UI có thể được tìm thấy tại https://localhost:<port>/swagger. Khám phá API thông qua Swagger UI và tích hợp nó vào các chương trình khác.
Mẹo: Để phục vụ Swagger UI tại root của ứng dụng (https://localhost:<port>/), đặt thuộc tính RoutePrefix thành chuỗi rỗng:
``csharp
if (builder.Environment.IsDevelopment())
{
app.UseSwaggerUI(options => // UseSwaggerUI chỉ được gọi trong Development.
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
options.RoutePrefix = string.Empty;
});
}
``
Nếu sử dụng thư mục với IIS hoặc reverse proxy (proxy ngược), đặt Swagger endpoint thành đường dẫn tương đối bằng tiền tố ./. Ví dụ: ./swagger/v1/swagger.json.
Lưu ý: Theo mặc định, Swashbuckle tạo và expose Swagger JSON trong phiên bản 3.0 của đặc tả — được gọi chính thức là OpenAPI Specification. Để hỗ trợ khả năng tương thích ngược, bạn có thể chọn expose JSON ở định dạng 2.0 bằng cách đặt thuộc tính SerializeAsV2 trong Program.cs:
``csharp
app.UseSwagger(options =>
{
options.SerializeAsV2 = true;
});
``
Tùy chỉnh và mở rộng
Swagger cung cấp các tùy chọn để tài liệu hóa object model và tùy chỉnh UI theo theme của bạn.
Thông tin và mô tả API
Action cấu hình được truyền vào phương thức AddSwaggerGen thêm thông tin như tác giả, giấy phép và mô tả.
Trong Program.cs, import namespace sau để sử dụng lớp OpenApiInfo:
using Microsoft.OpenApi.Models;
Sử dụng lớp OpenApiInfo để sửa đổi thông tin hiển thị trong UI:
builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "ToDo API",
Description = "An ASP.NET Core Web API for managing ToDo items",
TermsOfService = new Uri("https://example.com/terms"),
Contact = new OpenApiContact
{
Name = "Example Contact",
Url = new Uri("https://example.com/contact")
},
License = new OpenApiLicense
{
Name = "Example License",
Url = new Uri("https://example.com/license")
}
});
});Comment XML (XML comments)
Comment XML có thể được kích hoạt theo các cách sau. Thêm GenerateDocumentationFile vào file .csproj:
<PropertyGroup> <GenerateDocumentationFile>true</GenerateDocumentationFile> </PropertyGroup>
Kích hoạt comment XML cung cấp thông tin debug cho các kiểu public và thành viên chưa được tài liệu hóa. Để bỏ qua cảnh báo trên toàn dự án, định nghĩa danh sách mã cảnh báo cần bỏ qua phân cách bằng dấu chấm phẩy trong file dự án:
<PropertyGroup> <GenerateDocumentationFile>true</GenerateDocumentationFile> <NoWarn>$(NoWarn);1591</NoWarn> </PropertyGroup>
Để bỏ qua cảnh báo chỉ cho các thành viên cụ thể, bao quanh code bằng chỉ thị tiền xử lý #pragma warning:
namespace SwashbuckleSample.Models;
#pragma warning disable CS1591
public class TodoContext : DbContext
{
public TodoContext(DbContextOptions<TodoContext> options) : base(options) { }
public DbSet<TodoItem> TodoItems => Set<TodoItem>();
}
#pragma warning restore CS1591Cấu hình Swagger để sử dụng file XML được tạo với các hướng dẫn trên:
builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "ToDo API",
Description = "An ASP.NET Core Web API for managing ToDo items",
TermsOfService = new Uri("https://example.com/terms"),
Contact = new OpenApiContact
{
Name = "Example Contact",
Url = new Uri("https://example.com/contact")
},
License = new OpenApiLicense
{
Name = "Example License",
Url = new Uri("https://example.com/license")
}
});
// using System.Reflection;
var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
});Thêm comment triple-slash (///) vào một action sẽ nâng cao Swagger UI bằng cách thêm mô tả vào tiêu đề phần. Thêm phần tử <summary> bên trên action Delete:
/// <summary>
/// Deletes a specific TodoItem.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpDelete("{id}")]
public async Task<IActionResult> Delete(long id)
{
var item = await _context.TodoItems.FindAsync(id);
if (item is null)
{
return NotFound();
}
_context.TodoItems.Remove(item);
await _context.SaveChangesAsync();
return NoContent();
}Thêm phần tử <remarks> vào tài liệu action method Create. Nó bổ sung thông tin được chỉ định trong phần tử <summary> và cung cấp Swagger UI phong phú hơn. Nội dung của phần tử <remarks> có thể bao gồm văn bản, JSON hoặc XML:
/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <param name="item"></param>
/// <returns>A newly created TodoItem</returns>
/// <remarks>
/// Sample request:
///
/// POST /Todo
/// {
/// "id": 1,
/// "name": "Item #1",
/// "isComplete": true
/// }
///
/// </remarks>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> Create(TodoItem item)
{
_context.TodoItems.Add(item);
await _context.SaveChangesAsync();
return CreatedAtAction(nameof(Get), new { id = item.Id }, item);
}Data annotations (chú thích dữ liệu)
Đánh dấu model bằng các attribute trong namespace System.ComponentModel.DataAnnotations để giúp điều khiển các thành phần Swagger UI.
Thêm attribute [Required] vào thuộc tính Name của lớp TodoItem:
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace SwashbuckleSample.Models;
public class TodoItem
{
public long Id { get; set; }
[Required]
public string Name { get; set; } = null!;
[DefaultValue(false)]
public bool IsComplete { get; set; }
}Sự hiện diện của attribute này thay đổi hành vi UI và thay đổi JSON schema bên dưới.
Thêm attribute [Produces("application/json")] vào API controller. Mục đích là khai báo rằng các action của controller hỗ trợ kiểu nội dung response là application/json:
[ApiController]
[Route("api/[controller]")]
[Produces("application/json")]
public class TodoController : ControllerBase
{Mô tả kiểu response
Action Create trả về HTTP status code 201 khi thành công. HTTP status code 400 được trả về khi request body được post là null. Thêm các dòng được đánh dấu trong ví dụ sau để tài liệu hóa đúng:
/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <param name="item"></param>
/// <returns>A newly created TodoItem</returns>
/// <remarks>
/// Sample request:
///
/// POST /Todo
/// {
/// "id": 1,
/// "name": "Item #1",
/// "isComplete": true
/// }
///
/// </remarks>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> Create(TodoItem item)
{
_context.TodoItems.Add(item);
await _context.SaveChangesAsync();
return CreatedAtAction(nameof(Get), new { id = item.Id }, item);
}Convention (quy ước) có thể được dùng thay thế để tránh phải trang trí thủ công từng action với [ProducesResponseType]. Để biết thêm thông tin, xem Sử dụng web API conventions.
Tùy chỉnh UI
UI mặc định vừa chức năng vừa trình bày đẹp. Tuy nhiên, các trang tài liệu API nên đại diện cho thương hiệu hoặc theme của bạn. Việc xây dựng thương hiệu cho các thành phần Swashbuckle đòi hỏi thêm tài nguyên để phục vụ static file và xây dựng cấu trúc thư mục để lưu trữ các file đó.
Kích hoạt Static File Middleware (middleware file tĩnh):
app.UseHttpsRedirection(); app.UseStaticFiles(); app.MapControllers();
Để inject các stylesheet CSS bổ sung, thêm chúng vào thư mục wwwroot của dự án và chỉ định đường dẫn tương đối trong tùy chọn middleware:
if (app.Environment.IsDevelopment())
{
app.UseSwaggerUI(options => // UseSwaggerUI chỉ được gọi trong Development.
{
options.InjectStylesheet("/swagger-ui/custom.css");
});
}