Swashbuckle EF Core隐藏属性,用于发布/发布文档

问题描述

摘要

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

更多详细信息

我想为我正在使用的系统创建一个文档详尽的API。我想使用Swashbuckle / Swagger自动生成文档。我正在使用Entity Framework定义系统中对象之间的关系。

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

User.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,"name": "string","posts": [
      null
    ]
  }
}

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

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

POST / api / posts

{
  "id": 0,"name": "string"
  }
}

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

问题再次出现

是否仅存在用于PUT / POST方法的,从生成的swagger文档中抑制关系对象的优雅方法

解决方法

您可以自定义如下的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)
{...}

Startup.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();
    });
}

结果:

enter image description here