簡體   English   中英

ASP.NET核心中未綁定參數添加swagger參數

[英]Add swagger parameters for unbound parameters in ASP.NET Core

我有一個 ASP.NET Core 2.2 WebApi 並且想要上傳帶有一些額外元數據的大文件。 該請求是一個多部分/表單數據。 因為要上傳的文件可能會變得很大,所以我不想將其讀入 memory 進行處理,而是將 stream 直接讀入所需的目的地。 我按照文檔禁用了表單值 model 綁定,並且我還調整了端點的最大請求大小。

我已經用 postman 測試了端點,它按預期工作: 在此處輸入圖像描述

但是,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);
}

通常,我會像下面的例子那樣綁定參數:

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

這在 Swagger 中按預期工作,但如上所述,我不想綁定參數。

對於 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 }
                }
            };
        }
    }
}

您可以為此使用IOperationFilter 添加以下class,調整controller和動作名稱

public class AddUnboundParametersOperationFilter : IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {
        if (operation.Parameters == null)
            operation.Parameters = new List<IParameter>();

        var descriptor = context.ApiDescription.ActionDescriptor as ControllerActionDescriptor;

        if (descriptor != null && descriptor.ControllerTypeInfo == typeof(TestController) && descriptor.ActionName == nameof(TestController.Upload))
        {
            operation.Parameters.Add(new NonBodyParameter()
            {
                Name = "department",
                Type = "string",
                Required = true,
                In = "formData",
            });

            operation.Parameters.Add(new NonBodyParameter()
            {
                Type = "file",
                In = "formData",
                Name = "file",
                Required = true
            });
        }
    }
}

Startup.cs

services.AddSwaggerGen(c =>
{
    c.OperationFilter<AddUnboundParametersOperationFilter>();
    //...
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM