首页 > 解决方案 > Swashbuckle EF Core 隐藏发布/放置文档的属性

问题描述

概括

我想从为 PUT/POST 请求生成的文档模型中隐藏属性。

更多详情

我想为我正在开发的系统创建一个记录良好的 API。我想使用 Swashbuckle/Swagger 自动生成文档。我正在使用实体框架来定义系统中对象之间的关系。

这是对象之间的示例关系。

用户.cs

public class User
{
    public int Id { get; set; }
    public string ExternalReference { get; set; }
    public string Name { get; set; }

    public ICollection<Post> Posts { get; }
}

Post.cs

public class Post
{
    public int Id { get; set; }
    public string ExternalReference { get; set; }
    public string Content { get; set; }
    public int UserId { get; set; }

    public User User { get; set; }

}

以下示例值是为我的 GET /api/posts/{id} 端点生成的。

获取 /api/posts/{id}

{
  "id": 0,
  "externalReference": "string",
  "content": "string",
  "userId": 0,
  "user": {
    "id": 0,
    "externalReference": "string",
    "name": "string",
    "posts": [
      null
    ]
  }
}

这就是我想看到的,它也可能返回 User 对象。

以下是为我的 POST /api/posts 端点生成的示例值

发布 /api/posts

{
  "id": 0,
  "externalReference": "string",
  "content": "string",
  "userId": 0,
  "user": {
    "id": 0,
    "externalReference": "string",
    "name": "string"
  }
}

在我看来,至少我觉得示例的用户部分与 POST 或 PUT 无关,只有userId属性才是。在这个简单的示例中,生成的示例值并不算太糟糕,但是如果我开始拥有具有多个关系的对象,我觉得它会变得混乱。

又问了

是否有一种优雅的方法可以仅针对 PUT/POST 方法从生成的 swagger 文档中抑制关系对象?

标签: c#asp.net-coreentity-framework-coreswaggerswashbuckle

解决方案


您可以自定义 OperationFilter,如下所示:

public class CustomOperationFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        if (operation.OperationId == "Posts_post" || operation.OperationId == "Posts_put")
        {
            operation.RequestBody = new OpenApiRequestBody()
            {
                Content = new Dictionary<string, OpenApiMediaType> {
                {"application/json",
                    new OpenApiMediaType()
                    {

                        Schema = new OpenApiSchema(){
                            Example = new OpenApiObject
                                {
                                    ["ID"] = new OpenApiInteger(0),
                                    ["UserId"] = new OpenApiInteger(0),
                                    ["ExternalReference"] = new OpenApiString("string"),
                                    ["Content"] = new OpenApiString("string")
                                }
                        }
                    }
                }
            }
            };
        }
        else
        {
            return;
        }
       
    }
}

在 HttpVerb 属性上添加名称:

[HttpPut("{id}",Name = "Posts_put")]
public async Task<IActionResult> PutPost(int id, Post post)
{....}

[HttpPost(Name ="Posts_post")]
public async Task<ActionResult<Post>> PostPost(Post post)
{...}

启动.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
        c.OperationFilter<CustomOperationFilter>();   //add this...
    });
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseSwagger();
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
    });

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

结果:

在此处输入图像描述


推荐阅读