英文:
Swashbuckle/Swagger: How to declare a custom type for OpenAPI annotations without using it as a request parameter
问题
在我的ASP.NET Core应用程序中,我有一个需要手动加载请求正文作为流的操作,使用HttpContext.Request.Body
。在这种情况下,我无法使用DTO作为请求参数。但是,尽管DTO不会用于处理请求正文,我仍然希望为OpenAPI注释和文档目的声明自定义类型。
以下是当前的代码片段:
[HttpPost]
[Route("api/upload")]
[Consumes("multipart/form-data")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> UploadDataAsync()
{
// 使用HttpContext.Request.Body手动读取请求正文
return NoContent();
}
我需要声明一个自定义类型作为我的请求载荷,类似于这样:
[HttpPost]
[Route("api/upload")]
[Consumes("multipart/form-data")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[SwaggerRequestBody(typeof(SomeDTO))] /* 类似于这个属性! */
public async Task<IActionResult> UploadDataAsync()
{
// 使用HttpContext.Request.Body手动读取请求正文
return NoContent();
}
请注意,DTO仅用于指定OpenAPI注释,实际上并未在请求处理中使用。
是否有一种方法可以在不使用DTO作为请求参数的情况下实现这一点?我想要确保准确的API文档,同时仍然可以手动处理HttpContext.Request.Body
。我知道可以实现自定义的IOperationFilter
,但这将需要手动创建带有所有属性的模式。我正在寻找一种避免手动创建模式的更简单方法。
英文:
I have an action in my ASP.NET Core application that needs to manually load the request body as a stream using HttpContext.Request.Body
. In this case, I cannot use a DTO as a request parameter. However, I would still like to declare a custom type for OpenAPI annotations and documentation purposes, even though the DTO won't be used to handle the request body.
Here is the current code snippet:
[HttpPost]
[Route("api/upload")]
[Consumes("multipart/form-data")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> UploadDataAsync()
{
// Use the HttpContext.Request.Body to read the body manually
return NoContent();
}
I need to declare a custom type as my request payload. Something like this:
[HttpPost]
[Route("api/upload")]
[Consumes("multipart/form-data")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[SwaggerRequestBody(typeof(SomeDTO))] /* Something like this attribute! */
public async Task<IActionResult> UploadDataAsync()
{
// Use the HttpContext.Request.Body to read the body manually
return NoContent();
}
Please note that the DTO is only used for specifying the OpenAPI annotations and is not actually used in the request processing.
Is there a way to achieve this without using the DTO as a request parameter? I want to ensure accurate API documentation while still manually handling the request body using HttpContext.Request.Body
. I'm aware that I can implement a custom IOperationFilter
, but this would require manually creating the schema with all of the properties. I'm looking for a simpler approach that avoids the need to create the schema myself.
答案1
得分: 2
这里是如何使用IOperationFilter
来定义自己的请求体合同的想法:
public sealed class AnyBodyFilter<T> : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var schema = context.SchemaGenerator.GenerateSchema(typeof(T), context.SchemaRepository);
operation.RequestBody = new OpenApiRequestBody
{
Content =
{
["multipart/form-data"] = new OpenApiMediaType
{
Schema = schema,
}
}
};
}
}
然后,在您的操作上使用[SwaggerOperationFilter(typeof(AnyBodyFilter<SomeDTO>))]
属性进行装饰,就应该完成了。
英文:
Here the idea how you can use IOperationFilter
to define your own contract for body:
public sealed class AnyBodyFilter<T> : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var schema = context.SchemaGenerator.GenerateSchema(typeof(T), context.SchemaRepository);
operation.RequestBody = new OpenApiRequestBody
{
Content =
{
["multipart/form-data"] = new OpenApiMediaType
{
Schema = schema,
}
}
};
}
}
Then decorate your action with attribute [SwaggerOperationFilter(typeof(AnyBodyFilter<SomeDTO>))]
and it's should be done.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论