【问题标题】:Asp.Net Core swagger Help Pages for IFormFile用于 IFormFile 的 Asp.Net Core swagger 帮助页面
【发布时间】:2016-08-21 21:58:08
【问题描述】:

我正在尝试设置 swagger 来测试具有 IFormFile 属性的模型。 例如我有下一个 api 方法

[HttpPost]
public ApiResult<UserModel> SaveTestFileData([FromForm]TestPostFileArgs args)
{
    var result = new UserModel() { Id = 1, Name = $"SaveTestFileData {args.UserId} company: {args.CompanyId}, file length: {args.CompanyFile.Length}" };
    return ApiResult.Success(result);
}

还有我的参数模型

public class TestPostFileArgs
{
    public int UserId { get; set; }
    public int? CompanyId { get; set; }
    public IFormFile CompanyFile { get; set; }
}

默认 swagger 生成不允许测试的帮助页面 为了解决这个问题,我写了下一个 OperationFilter

public class FormFileOperationFilter: IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {
        if (operation.Parameters == null)
            return;

        var fileParamNames = context.ApiDescription.ActionDescriptor.Parameters
            .SelectMany(x => x.ParameterType.GetProperties())
            .Where(x => x.PropertyType.IsAssignableFrom(typeof (IFormFile)))
            .Select(x => x.Name)
            .ToList();
        if (!fileParamNames.Any())
            return;

        var paramsToRemove = new List<IParameter>();
        foreach (var param in operation.Parameters)
        {
            paramsToRemove.AddRange(from fileParamName in fileParamNames where param.Name.StartsWith(fileParamName + ".") select param);
        }
        paramsToRemove.ForEach(x => operation.Parameters.Remove(x));
        foreach (var paramName in fileParamNames)
        {
            var fileParam = new NonBodyParameter
                {
                    Type = "file",
                    Name = paramName,
                    In = "formData"
                };
            operation.Parameters.Add(fileParam);
        }
        foreach (IParameter param in operation.Parameters)
        {
            param.In = "formData";
        }

        operation.Consumes = new List<string>() { "multipart/form-data" };
    }
}

在这之后,一切都按照我对 swagger 的期望工作。

目前这个解决方案对我有用,但感觉不对。也许我错过了一些简单的解决方案。此外,这种方法不使用 IFormFile 或其他方式处理 List 或复杂对象属性。

【问题讨论】:

  • 谢谢,我正在找这个!

标签: asp.net-web-api asp.net-core swagger


【解决方案1】:

对于 ASP.NET Core 开发人员,在 Swashbuckle.AspNetCore GitHub 存储库中为此编写了一个问题:https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/193。它在 cmets 中也有一些 OperationFilter 的工作代码——在这个问题中,一个对我来说比其他的工作得更好。

【讨论】:

    【解决方案2】:

    我有同样的问题,你的解决方案帮助了我。

    我刚刚更改了 OperationFilter,因为我的 IFormFile 参数不是嵌套参数,而是操作方法的主要参数。

    public class AddFileUploadParams : IOperationFilter
    {
        public void Apply(Operation operation, OperationFilterContext context)
        {
            if (operation.Parameters == null)
                return;
    
            var formFileParams = context.ApiDescription.ActionDescriptor.Parameters
                                    .Where(x => x.ParameterType.IsAssignableFrom(typeof(IFormFile)))
                                    .Select(x => x.Name)
                                    .ToList(); ;
    
            var formFileSubParams = context.ApiDescription.ActionDescriptor.Parameters
                .SelectMany(x => x.ParameterType.GetProperties())
                .Where(x => x.PropertyType.IsAssignableFrom(typeof(IFormFile)))
                .Select(x => x.Name)
                .ToList();
    
            var allFileParamNames = formFileParams.Union(formFileSubParams);
    
            if (!allFileParamNames.Any())
                return;
    
            var paramsToRemove = new List<IParameter>();
            foreach (var param in operation.Parameters)
            {
                paramsToRemove.AddRange(from fileParamName in allFileParamNames where param.Name.StartsWith(fileParamName + ".") select param);
            }
            paramsToRemove.ForEach(x => operation.Parameters.Remove(x));
            foreach (var paramName in allFileParamNames)
            {
                var fileParam = new NonBodyParameter
                {
                    Type = "file",
                    Name = paramName,
                    In = "formData"
                };
                operation.Parameters.Add(fileParam);
            }
            foreach (IParameter param in operation.Parameters)
            {
                param.In = "formData";
            }
    
            operation.Consumes = new List<string>() { "multipart/form-data" };
        }
    }
    

    我想您使用SwashBuckle 来生成招摇。 如果 swashBuckle 能处理这个就好了。如果我有时间的话,也许我会做出贡献。

    【讨论】:

    • 这不会编译
    【解决方案3】:

    使用

       [Route("picture/pics/upload/")]
    

    在路线中 和

    UploadPicture(IFormFile file)
    

    在方法中 完整的代码是

        [Route("picture/{Id:int:min(1)}/{sequence:int:min(1)}")]
        [SwaggerResponse((int)HttpStatusCode.NotFound)]
        [SwaggerResponse((int)HttpStatusCode.BadRequest)]
        [SwaggerResponse((int)HttpStatusCode.InternalServerError)]
        [SwaggerResponse((int)HttpStatusCode.OK, "The picture uploaded")]
        [SwaggerOperation(
            Summary = "upload a picture for new picture",
            Description = "This action upload a picture for new picture",
            OperationId = "UploadPictureAsync",
            Tags = new[] { "Pictures:Post" }
        )]
        public async Task<ActionResult> UploadPictureAsync(int storeId, byte 
        sequence, IFormFile file )
        {
           ...
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-08
      • 1970-01-01
      • 2018-11-24
      • 2023-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多