.NET Core API框架实战(三) 使用Swagger文档实现上传文件

8 篇文章 2 订阅
3 篇文章 0 订阅
  1. 介绍

  2. 在Swagger中利用 IOperationFilter 操作来实现文件上传

  3. 文件上传

1、介绍 

写过接口的朋友都知道,调试、维护接口是一件非常重要的一件事;swagger是一款非常不错的接口文档工具,那么在本期中,我们就用swagger接口文档来实现文件上传功能;话不多说,直接进入主题;

2、 在Swagger中利用 IOperationFilter 操作来实现文件上传

首先创建一个类,取名 SwaggerFileHeaderParameter,并继承为IOperationFilter

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

            if (!context.ApiDescription.HttpMethod.Equals("POST", StringComparison.OrdinalIgnoreCase) &&
                !context.ApiDescription.HttpMethod.Equals("PUT", StringComparison.OrdinalIgnoreCase))
            {
                return;
            }

            var fileParameters = context.ApiDescription.ActionDescriptor.Parameters.Where(n => n.ParameterType == typeof(IFormFile)).ToList();

            if (fileParameters.Count < 0)
            {
                return;
            }

            foreach (var fileParameter in fileParameters)
            {
                if (fileParameter.BindingInfo == null)
                {
                    operation.Parameters.Add(new NonBodyParameter
                    {
                        Name = fileParameter.Name,
                        In = "formData",
                        Description = "文件上传",
                        Required = true,
                        Type = "file"
                    });
                    operation.Consumes.Add("multipart/form-data");
                }
                else
                {
                    var parameter = operation.Parameters.Single(n => n.Name == fileParameter.Name);
                    operation.Parameters.Remove(parameter);
                    operation.Parameters.Add(new NonBodyParameter
                    {
                        Name = parameter.Name,
                        In = "formData",
                        Description = parameter.Description,
                        Required = parameter.Required,
                        Type = "file"
                    });
                    operation.Consumes.Add("multipart/form-data");
                }

            }  
        }
    }

第二步,在Startup中注册SwaggerFileHeaderParameter

  c.OperationFilter<SwaggerFileHeaderParameter>();

文件上传标签已注册完毕;

3、文件上传

注意:

.Net Core 是通过该类 IFormFile 进行文件上传,WebApi默认集成ControllerBase,但IFormFile必须基于Controller;

好,那我们直接上代码吧。

 /// <summary>
    /// 文件上传
    /// </summary>
    [Route("[controller]/[action]")]
    public class HomeController : Controller
    {
        private readonly IHostingEnvironment _hostingEnvironment;
        private readonly SystemConfig config;
        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="hostingEnvironment"></param>
        /// <param name="options"></param>
        public HomeController(
            IHostingEnvironment hostingEnvironment,
            IOptions<SystemConfig> options
            )
        {
            _hostingEnvironment = hostingEnvironment;//依赖注入类,因为.net core 已经没有Server.MapPath()属性了
            config = options.Value;
        }
        /// <summary>
        /// 上传图片
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> UploadImg(UploadInput input)
        {
            try
            {
                var date = Request;
                var files = Request.Form.Files;
                if (files.Count == 0)
                    return Ok($"图片未上传,请上传文件");
                long size = files.Sum(f => f.Length);//获取文件大小
                if (size > config.FileFormat.Img.B)
                    return Ok($"图片过大,图片大小为{config.FileFormat.Img.Size}M");
                string webRootPath = _hostingEnvironment.WebRootPath;
                string contentRootPath = _hostingEnvironment.ContentRootPath;//获取服务器路径
                //存储文件名路径
                foreach (var formFile in files)
                {
                    if (formFile.Length > 0)
                    {
                        string fileExt = formFile.FileName.Substring(formFile.FileName.LastIndexOf('.'), formFile.FileName.Length - formFile.FileName.LastIndexOf('.'));//获取后缀名
                        if (!config.FileFormat.Img.Exts().Contains(fileExt.ToLower()))
                            return Ok($"图片格式不正确,图片为格式为{config.FileFormat.Img.ExtStr}");
                        long fileSize = formFile.Length; //获得文件大小,以字节为单位
                        var newFileName = Guid.NewGuid().ToString() + fileExt; //随机生成新的文件名
                        string path = $"{webRootPath}/Content/Upload/{input.FolderName}";//文件夹路径
                        if (!PathHelper.IsExist(path))//查询目录是否存在
                            PathHelper.CreateFiles(path);//创建目录
                        var filePath = $"{path}/{ newFileName}";//文件路径
                        using (var stream = new FileStream(filePath, FileMode.Create))
                        {
                            await formFile.CopyToAsync(stream);
                            //备份文件
                            PathHelper.Backup(filePath, $"{config.FileFormat.BackupUrl}/{input.FolderName}", newFileName);
                        }
                    }
                }
                return Ok("上传成功");
            }
            catch (Exception ex)
            {
                return Ok(ex.Message);
            }
        }
    }

附加:备份文件


    public static class PathHelper
    {
        /// <summary>
        /// 是否是绝对路径
        /// windows下判断 路径是否包含 ":"
        /// Mac OS、Linux下判断 路径是否包含 "\"
        /// </summary>
        /// <param name="path">路径</param>
        /// <returns></returns>
        public static bool IsAbsolute(string path)
        {
            return Path.VolumeSeparatorChar == ':' ? path.IndexOf(Path.VolumeSeparatorChar) > 0 : path.IndexOf('\\') > 0;
        }
        /// <summary>
        /// 路径是否存在
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static bool IsExist(string path)
        {
            return Directory.Exists(path);
        }
        /// <summary>
        /// 创建目录
        /// </summary>
        /// <param name="path"></param>
        public static void CreateFiles(string path)
        {
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
        }
        /// <summary>
        /// 备份文件
        /// </summary>
        /// <param name="sourcefile">文件路径</param>
        /// <param name="targetfile">备份文件路径</param>
        /// <param name="filename">文件名</param>
        public static void Backup(string sourcefile, string targetfile, string filename)
        {
            if (!Directory.Exists(targetfile))
            {
                Directory.CreateDirectory(targetfile);
            }
            File.Copy(sourcefile, $"{targetfile}/{filename}", true);
        }
    }

好,讲到这里本期也告一段落了,现在我们一起来实现一下上传文件吧!

运行项目

可以看到我们刚刚创建的上传文件标签;

可以看到我们上传的文件。

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值