问题描述
更多详细信息
我想为我正在使用的系统创建一个文档详尽的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();
});
}
结果: