c# - 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 文档中抑制关系对象?
解决方案
您可以自定义 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();
});
}
结果:
推荐阅读
- c# - 将 C# 转换为 Visual Basic Shopify WebRequests 停止运行
- javascript - 为什么变量没有在 created() 方法中定义
- postgresql - 如何在没有 pg_dump 的情况下将我的所有表从 Postgres 数据库复制到另一个?
- javascript - 如何调整模态框的大小?
- java - spring boot 中创建预定方法的最佳实践
- python-3.x - python Osmnx上的RuntimeError
- html - 侧面固定菜单在 div 下方重叠
- cmd - 等到程序启动
- python - 使用python比较excel中的两列和颜色更大?
- python - imageio:AttributeError:“模块”对象没有属性“imread”