简体   繁体   English

Swashbuckle EF Core 隐藏发布/放置文档的属性

[英]Swashbuckle EF Core hide properties for post/put documentation

Summary概括

I would like to hide properties from the generated documentation model for PUT/POST requests.我想从为 PUT/POST 请求生成的文档模型中隐藏属性。

More Detail更多详情

I would like to create a nicely documented API for a system I'm working on.我想为我正在使用的系统创建一个记录良好的 API。 I would like to use Swashbuckle/Swagger to automatically generate the documentation.我想使用 Swashbuckle/Swagger 自动生成文档。 I am using Entity Framework to define the relationship between objects in the system.我正在使用实体框架来定义系统中对象之间的关系。

Here is an example relationship between objects.这是对象之间的示例关系。

User.cs用户.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 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; }

}

The following example value is generated for my GET /api/posts/{id} endpoint.以下示例值是为我的 GET /api/posts/{id} 端点生成的。

GET /api/posts/{id}获取/api/posts/{id}

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

This is what I would like to see, it's relevant to potentially return the User object as well.这就是我希望看到的,它也与可能返回 User 对象有关。

The following is the example value generated for my POST /api/posts endpoint以下是为我的 POST /api/posts 端点生成的示例值

POST /api/posts POST /api/posts

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

In my mind at least I feel the user section of the example isn't relevant for POST or PUT only the userId property is.在我看来,至少我觉得示例的用户部分与 POST 或 PUT 无关,只有userId属性才是。 The generated example value isn't too bad in this simple example, but if I start having objects with multiple relationships I feel it can get messy.在这个简单的示例中,生成的示例值还不错,但是如果我开始使用具有多个关系的对象,我觉得它会变得混乱。

The question again又问

Is there an elegant way of supressing relational objects from the generated swagger documentation ONLY for PUT/POST methods?是否有一种优雅的方法可以仅针对 PUT/POST 方法从生成的 swagger 文档中抑制关系对象?

You could custom a OperationFilter like below:您可以自定义一个 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;
        }
       
    }
}

Add the name on HttpVerb attribute:在 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:启动.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();
    });
}

Result:结果:

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM