亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 Swashbuckle Swagger 上傳文件

使用 Swashbuckle Swagger 上傳文件

C#
繁星coding 2021-11-14 15:50:47
我有一個帶有 Swagger 3.0 的 ASP.NET Core 2 應用程序,我想通過從 Swagger UI 上傳文件來測試 POST 操作。文件上傳控制器:[ApiController]public class FileUploadController : ApiControllerBase{    private readonly IFileUploader _fileUploader;    public FileUploadController(IFileUploader fileUploader, ILogger<FileUploadController> logger) : base(logger)    {        _fileUploader = fileUploader;    }    [HttpPost]    [Route(nameof(UploadFile))]    public FileUploadResult UploadFile(IFormFile uploadedFile)    {        return _FileUploader.UploadFile(Request.Form.Files[0]);    }}閱讀 Swagger 文檔和其他主題,我發現我需要自定義 IOperationFilter,所以這就是我想出的:public class FileUploadOperationFilter : IOperationFilter{    public void Apply(Operation operation, OperationFilterContext context)    {        if (operation.OperationId.ToLower() == "apifileuploaduploadfilepost")        {            operation.Parameters.Add(new NonBodyParameter()            {                Name = "file",                In = "formData",                Description = "Upload File",                Required = true,                Type = "file"            });            operation.Consumes.Add("multipart/form-data");        }    }}它在 Swagger 啟動類中注冊:                options.OperationFilter<FileUploadOperationFilter>();因此,來自 IFormFile 的所有字段都消失了,而是有上傳文件控件,因此我可以選擇“試用”按鈕,選擇一個文件,但是在按“執行”后,我收到以下錯誤:web api 本身不會崩潰,也不會拋出任何錯誤。我在調試期間注意到的 -FileUploadController達到了 的構造函數但沒有觸發 FileUpload 方法。
查看完整描述

3 回答

?
largeQ

TA貢獻2039條經驗 獲得超8個贊

你能試試這個操作過濾器嗎:


/// <summary>

/// Filter to enable handling file upload in swagger

/// </summary>

public class FormFileSwaggerFilter : IOperationFilter

{

    private const string formDataMimeType = "multipart/form-data";

    private static readonly string[] formFilePropertyNames =

        typeof(IFormFile).GetTypeInfo().DeclaredProperties.Select(p => p.Name).ToArray();


    /// <summary>

    /// Applies the specified operation.

    /// </summary>

    /// <param name="operation">The operation.</param>

    /// <param name="context">The context.</param>

    public void Apply(Operation operation, OperationFilterContext context)

    {

        var parameters = operation.Parameters;

        if (parameters == null || parameters.Count == 0) return;


        var formFileParameterNames = new List<string>();

        var formFileSubParameterNames = new List<string>();


        ProcessActionParameters(context, ref formFileParameterNames, ref formFileSubParameterNames);


        if (!formFileParameterNames.Any()) return;


        var consumes = operation.Consumes;

        consumes.Clear();

        consumes.Add(formDataMimeType);


        ProcessParameters(ref parameters, formFileSubParameterNames);


        ProcessFormFileParameters(formFileParameterNames, ref parameters);

    }


    private static void ProcessFormFileParameters(List<string> formFileParameterNames, ref IList<IParameter> parameters)

    {

        foreach (var formFileParameter in formFileParameterNames)

        {

            parameters.Add(new NonBodyParameter()

            {

                Name = formFileParameter,

                Type = "file",

                In = "formData"

            });

        }

    }


    private static void ProcessActionParameters(OperationFilterContext context, ref List<string> formFileParameterNames,

        ref List<string> formFileSubParameterNames)

    {

        foreach (var actionParameter in context.ApiDescription.ActionDescriptor.Parameters)

        {

            var properties =

                actionParameter.ParameterType.GetProperties()

                    .Where(p => p.PropertyType == typeof(IFormFile))

                    .Select(p => p.Name)

                    .ToArray();


            if (properties.Length != 0)

            {

                formFileParameterNames.AddRange(properties);

                formFileSubParameterNames.AddRange(properties);

                continue;

            }


            if (actionParameter.ParameterType != typeof(IFormFile)) continue;

            formFileParameterNames.Add(actionParameter.Name);

        }

    }


    private static void ProcessParameters(ref IList<IParameter> parameters, List<string> formFileSubParameterNames)

    {

        foreach (var parameter in parameters.ToArray())

        {

            if (!(parameter is NonBodyParameter) || parameter.In != "formData") continue;


            if (formFileSubParameterNames.Any(p => parameter.Name.StartsWith(p + "."))

                || formFilePropertyNames.Contains(parameter.Name))

                parameters.Remove(parameter);

        }

    }

}



查看完整回答
反對 回復 2021-11-14
?
喵喔喔

TA貢獻1735條經驗 獲得超5個贊

表單中的鍵應該與方法中的參數匹配,在過濾器中重命名:


operation.Parameters.Add(new NonBodyParameter()

            {

                Name = "uploadedFile",

                In = "formData",

                Description = "Upload File",

                Required = true,

                Type = "file"

            });


查看完整回答
反對 回復 2021-11-14
?
冉冉說

TA貢獻1877條經驗 獲得超1個贊

通過從參數中刪除 IFormFile 上傳文件來解決:


    [HttpPost]

[Route(nameof(UploadFile))]

public FileUploadResult UploadFile()

{

    return _FileUploader.UploadFile(Request.Form.Files[0]);

}


查看完整回答
反對 回復 2021-11-14
  • 3 回答
  • 0 關注
  • 423 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號