c# - 为 ASP.NET Core 中的未绑定(bind)参数添加 swagger 参数

标签 c# asp.net-core asp.net-web-api swagger multipartform-data

我有一个 ASP.NET Core 2.2 WebApi,想上传带有一些额外元数据的大文件。该请求是一个多部分/表单数据。因为要上传的文件可能会变得非常大,所以我不想将其读入内存进行处理,而是直接将其流式传输到所需的目的地。 我关注了documentation禁用表单值模型绑定(bind),我还调整了端点的最大请求大小。

我已经用 postman 测试了端点,它按预期工作: enter image description here

但是,Swagger显然不承认请求应该有参数。如何在不在方法签名中定义参数的情况下将这些参数添加到 swagger 文档中?

我的端点类似于以下示例:

[HttpPost]
[DisableFormValueModelBinding]
[DisableRequestSizeLimit]
public async Task<IActionResult> Upload() // "department" and "file" needed in the multipart/form-data
{
  // var path = await uploader.UploadAsync(Request);
  // return Ok(path);
}

通常,我会像下面的例子那样绑定(bind)参数:

public async Task<IActionResult> Upload([FromForm] string department, [FromForm] IFormFile file)

这在 Swagger 中按预期工作,但如上所述,我不想绑定(bind)参数。

最佳答案

对于 Swashbuckle.AspNetCore 版本 5 和更高版本,一些事情发生了变化。

要像 Alexander 在他的回答中那样提供参数,代码将如下所示:

operation.Parameters.Add(new OpenApiParameter()
{
    Name = "department",
    Schema = new OpenApiSchema { Type = "string", Format = "string" },
    Required = true,
});

operation.Parameters.Add(new OpenApiParameter()
{
    Name = "file",
    Schema = new OpenApiSchema { Type = "string", Format = "binary" },
    Required = true,
});

但是出于某种原因(我没有进一步调查),我无法使用这种方法在 Swagger UI 中执行调用。

最后,以下示例为我提供了我正在寻找的结果:

public class AddUnboundParametersOperationFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        var descriptor = context.ApiDescription.ActionDescriptor as ControllerActionDescriptor;
    
        if (descriptor != null && descriptor.ControllerTypeInfo == typeof(RemoteUpdateController) && descriptor.ActionName == nameof(RemoteUpdateController.Upload))
        {
            var openApiMediaType = new OpenApiMediaType
            {
                Schema = new OpenApiSchema
                {
                    Type = "object",
                    Required = new HashSet<string> { "department", "file" }, // make the parameter(s) required if needed
                    Properties = new Dictionary<string, OpenApiSchema>
                    {
                        { "department" , new OpenApiSchema() { Type = "string", Format = "string" } },
                        { "file" , new OpenApiSchema() { Type = "string", Format = "binary" } },
                    }
                }
            };

            operation.RequestBody = new OpenApiRequestBody
            {
                Content = new Dictionary<string, OpenApiMediaType>
                {
                    { "multipart/form-data", openApiMediaType }
                }
            };
        }
    }
}

关于c# - 为 ASP.NET Core 中的未绑定(bind)参数添加 swagger 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66256229/

相关文章:

c# - 测试接口(interface)实现是好的设计吗?

c# - 使用 Json.NET lib 通过 json 发送 javascript 函数

c# - 如何使用 XmlSerializer 在不同级别指定 XmlElement?

c# - 将 netcore IConfigurationSection 绑定(bind)到动态对象

asp.net-web-api - ASP.NET Web API 和授权

c# - 在类库中执行asp.net core EF迁移,无需硬编码连接字符串

asp.net-core - 如何在 asp.net 核心 MVC Controller 中使用 ReadAsStringAsync?

mysql - 通过反射确定泛型 TEntity 的哪些 PropertyInfo 是主键

c# - WebAPI OData 无法加载 microsoft.data.odata 版本=5.6.0.0

php - 脚本添加不起作用