-
介绍
-
在Swagger中利用 IOperationFilter 操作来实现文件上传
-
文件上传
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); } }
好,讲到这里本期也告一段落了,现在我们一起来实现一下上传文件吧!
运行项目
可以看到我们刚刚创建的上传文件标签;
可以看到我们上传的文件。