将Swagger描述添加到最小的.NET 6 API。

16

我有一个使用 .NET 6 编写的小型项目,其中包含类似于这样的最小 API。

app.MapGet("/clients",
     async (IClientRepository repo) =>
     {
          var results = await repo.GetClientsAsync();
          return mapper.Map<IEnumerable<ClientModel>>(results);
     });

SwaggerUI 中,我可以使用这个 API,但是我找不到添加描述的方法(尽管在项目设置中我勾选了创建 API XML 文档)。

enter image description here

如何添加XML注释?
5个回答

27

目前对于最小API的Open API文档的支持相当简约,据我所见,不允许添加描述/摘要。计划在.NET 7中添加描述功能。此外,Swashbuckle很快应该考虑使用EndpointMetadata进行注释

还有相关问题

更新

通过最新的Swashbuckle nuget包和Swashbuckle.AspNetCore.Annotations更新,您可以为端点添加描述:

builder.Services.AddSwaggerGen(opts => opts.EnableAnnotations());

app.MapGet("/weatherforecast", () =>
{
    // Implementation
})
.WithMetadata(new SwaggerOperationAttribute(summary: "Summary", description: "Descritption Test"));

// Or

app.MapGet("/weatherforecast1", [SwaggerOperation(summary: "Summary1", description: "Descritption Test1")] () =>
{
    // Implementation
});

更新 2

对于 .NET 7 和最新的 Swashbuckle.AspNetCore 包,也可以使用 WithDescription 方法:

builder.Services.AddSwaggerGen();
...

app.MapGet("/weatherforecast", () =>
{
    // implementation
})
.WithDescription("Some Method Description")
.WithOpenApi();

或者使用EndpointDescriptionAttribute
app.MapGet("/weatherforecast1", [EndpointDescription("Some Attribute description")] () =>
{
    // implementation
})
.WithOpenApi();

3
我想补充一下,WithOpenApi 方法可以在 Microsoft.AspNetCore.OpenApi NuGet 包中找到。 - Philip Voloshin
2
WithOpenApi 扩展方法还支持通过传递委托来设置操作的描述,例如 operation => operation.Description = "foo"; return operation;。这种方式更加强大,因为您可以修改整个操作。 - Safia Abdalla
虽然提供的一些解决方案适用于文档的某些部分(如摘要和描述),但我似乎找不到有关记录参数的任何信息。是否有人遇到过适当添加参数文档的方法? - Xorcist
据我所知,.NET 7应该支持来自XML注释的Swagger文档 - 你可以尝试一下。或者试着使用 Swashbuckle.AspNetCore.Annotations 中的 SwaggerParameterAttribute 标记参数。 - Guru Stron
1
我找到了参数未记录的根本原因(在我的情况下)。事实证明,如果使用.WithOpenApi()定义最小API端点映射,则不会处理参数,但是如果取消该方法调用,则一切都按预期工作。 - Xorcist
支持基于XML的OpenAPI文档用于最小API。#39927 https://github.com/dotnet/aspnetcore/issues/39927 目前还未计划在.Net 8中实现。 - Michael Freidgeim

14

Swashbuckle.AspNetCore.Annotations 版本号为 6.3

...
builder.Services.AddSwaggerGen(c => c.EnableAnnotations());

var app = builder.build();

app.MapGet("/clients",
    [SwaggerOperation(
        Summary = "returns clients",
        Description = "more description on get `clients`")]
    [SwaggerResponse(200, "success")]
    [SwaggerResponse(500, "some failure")]
    async (IClientRepository repo) =>
    {
        var results = await repo.GetClientsAsync();
        return mapper.Map<IEnumerable<ClientModel>>(results);
    }).WithTags("Clients");

更多示例,请参见https://github.com/domaindrivendev/Swashbuckle.AspNetCore#enrich-operation-metadata


13

1. 安装包

dotnet add package Swashbuckle.AspNetCore.Annotations

2. 编写代码

// Program.cs

builder.Services.AddSwaggerGen(x =>
{
  x.EnableAnnotations();
});

// app.MapGet("/hi", [SwaggerOperation(Summary = "summary001", Description = "description001 `adads`")] () => "Hi");

app.MapGet("/hi", () => "Hi")
  .WithMetadata(new SwaggerOperationAttribute("summary001", "description001"));

结果

在此输入图片描述

这个页面显示了一个名为“结果”的标题,并展示了一张图片。

2

你可以使用扩展方法来更清晰地记录API端点。这样,你可以为每个端点定义通用的响应方法。

为此,你需要安装以下软件包:

Swashbuckle.AspNetCoreSwashbuckle.AspNetCore.Annotations

using Microsoft.AspNetCore.Authorization;
using Swashbuckle.AspNetCore.Annotations;


public static class MinimalAttributeExtensions
{
    public static RouteHandlerBuilder AllowAnonymous(this RouteHandlerBuilder endpoint)
    {
        endpoint.WithMetadata(new AllowAnonymousAttribute());
        return endpoint;
    }
    public static RouteHandlerBuilder Authorize(this RouteHandlerBuilder endpoint, string policy = null, string[] roles = null, params string[] schemes)
    {
        var authorizeAttribute = new AuthorizeAttribute();

        if (!string.IsNullOrEmpty(policy))
        {
            authorizeAttribute.Policy = policy;
        }

        if (roles != null && roles.Any())
        {
            authorizeAttribute.Roles = string.Join(',', roles);
        }

        if (schemes != null && schemes.Any())
        {
            authorizeAttribute.AuthenticationSchemes = string.Join(',', schemes);
        }

        endpoint.WithMetadata(authorizeAttribute);

        return endpoint;
    }
    public static RouteHandlerBuilder AddMetaData<T>(this RouteHandlerBuilder endpoint, string tag, string summary = null, string description = null)
    {
        endpoint.WithTags(tag);

        endpoint.WithMetadata(new SwaggerOperationAttribute(summary, description));

        endpoint.WithMetadata(new SwaggerResponseAttribute(200, type: typeof(T)))
                .WithMetadata(new SwaggerResponseAttribute(500, type: typeof(ErrorResponseModel)))
                .WithMetadata(new SwaggerResponseAttribute(400, type: typeof(ErrorResponseModel)))
                .WithMetadata(new SwaggerResponseAttribute(404, type: typeof(ErrorResponseModel)))
                .WithMetadata(new SwaggerResponseAttribute(422, type: typeof(ErrorResponseModel)))
                .WithMetadata(new SwaggerResponseAttribute(304, type: typeof(ErrorResponseModel)));

        return endpoint;
    }
    public static RouteHandlerBuilder AddMetaData(this RouteHandlerBuilder endpoint, string tag, string summary = null, string description = null)
    {
        endpoint.WithTags(tag);

        endpoint.WithMetadata(new SwaggerOperationAttribute(summary, description));

        endpoint.WithMetadata(new SwaggerResponseAttribute(500, type: typeof(ErrorResponseModel)))
                .WithMetadata(new SwaggerResponseAttribute(400, type: typeof(ErrorResponseModel)))
                .WithMetadata(new SwaggerResponseAttribute(404, type: typeof(ErrorResponseModel)))
                .WithMetadata(new SwaggerResponseAttribute(422, type: typeof(ErrorResponseModel)))
                .WithMetadata(new SwaggerResponseAttribute(304, type: typeof(ErrorResponseModel)));

        return endpoint;
    }
}

以下是如何使用这些扩展方法的示例:
app.MapGet(“/books”, async (BooksDB db) =>
{
    return await db.Books.ToListAsync()
})
.Authorize(policy : "AdminOnly", roles : new string[] {1,2}, schemes: "Bearer")
.AddMetaData<List<Book>>
(
    tag : "Books",
    summary : "Get All Books",
    description : "Get All Books in List, Roles Allowed => Admin Only"
);

这里的.AddMetaData<T>表示成功的响应模型,它也会添加到此端点的响应文档中。在这种情况下,它是List<Book>


1

您可以使用这个指南。我使用Swashbuckle工作,这里有一些附带于minimal API的扩展方法。这是它的样子:

app.MapGet(“/books”, async (BooksDB db) =>
await db.Books.ToListAsync()
)
.Produces<List<Book>>(StatusCodes.Status200OK)
.WithName(“GetAllBooks”).WithTags(“Getters”);

这个链接没有解释如何添加评论。 - Enrico Rossini

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接