加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-web-api – 用于IFormFile的Asp.Net Core swagger帮助页

发布时间:2020-12-16 06:55:11 所属栏目:asp.Net 来源:网络整理
导读:我试图设置swagger来测试具有IFormFile属性的模型. 例如,我有下一个api方法 [HttpPost]public ApiResultUserModel SaveTestFileData([FromForm]TestPostFileArgs args){ var result = new UserModel() { Id = 1,Name = $"SaveTestFileData {args.UserId} com
我试图设置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生成帮助页面,不允许对其进行测试

Wrong swagger ui


为了解决这个问题,我写了下一个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" };
    }
}

在这种情况发生之后,正如我所期待的那样.

Correct swagger ui

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

解决方法

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

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

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",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会处理这个问题会很好.如果我还有时间,也许我会做出贡献.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读