Nguon: Microsoft Learn · .NET 8.0

Bắt đầu với Swashbuckle và ASP.NET Core

Nguồn: Get started with Swashbuckle and 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:

Cài đặt package

Swashbuckle có thể được thêm vào theo các cách sau:

Visual Studio

``powershell Install-Package Swashbuckle.AspNetCore -Version 6.6.2 ``

Visual Studio Code

Chạy lệnh sau từ Integrated Terminal:

dotnetcli
dotnet add TodoApi.csproj package Swashbuckle.AspNetCore -v 6.6.2

.NET CLI

Chạy lệnh sau:

dotnetcli
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:

csharp
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:

csharp
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:

csharp
using Microsoft.OpenApi.Models;

Sử dụng lớp OpenApiInfo để sửa đổi thông tin hiển thị trong UI:

csharp
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:

xml
<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:

xml
<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:

csharp
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 CS1591

Cấu hình Swagger để sử dụng file XML được tạo với các hướng dẫn trên:

csharp
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:

csharp
/// <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:

csharp
/// <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:

csharp
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:

csharp
[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:

csharp
/// <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):

csharp
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:

csharp
if (app.Environment.IsDevelopment())
{
    app.UseSwaggerUI(options => // UseSwaggerUI chỉ được gọi trong Development.
    {
        options.InjectStylesheet("/swagger-ui/custom.css");
    });
}

Tài nguyên bổ sung