使用swagger上传文件
经常使用swagger,可以通过设置[ProducesResponseType]标记接口的返回信息;swagger也能通过接口的参数列表,自动获得发送的数据结构信息。
不过有一个例外,就是上传文件的时候,设置了[Consumes]的内容为multi-part/form-data,但是swagger并不能正常感知是上传文件的。代码是这个样子的:
关于文件上传的细节,可以看多年前我写过一篇有关通过WEBAPI上传文件的文章。
[Consumes("multipart/form-data")]
[ODataRoute]
[HttpPost]
public async Task<ActionResult> Post(IFormCollection collection)
{
var file = collection.Files[0];
if(file != null)
{
var filename = DateTime.Now.ToString("yyyyMMddHHmmss") + file.FileName;
var path = Path.Combine(_webHostEnvironment.WebRootPath, "Files", filename);
using FileStream fileStream = new FileStream(path, FileMode.Create);
await file.CopyToAsync(fileStream);
var uri = "Files/" + filename;
var fileEntity = new Models.File { Url = uri, LastModified = DateTime.Now };
_homeworkDataContext.Files.Add(fileEntity);
await _homeworkDataContext.SaveChangesAsync();
return Created(WebUtility.UrlEncode(uri), fileEntity);
}
return BadRequest();
}
实际上,swagger一直提示,上传的内容是一个array类型,当然API是没有问题的,可以通过POSTMAN进行发送,不过不能在网页上直接操作,总觉得心里有点不太舒服。

方法
搜索了一下办法,比较靠谱的,就是通过增加一个IOperationFilter来实现目的。
// CODE FROM https://www.talkingdotnet.com/how-to-upload-file-via-swagger-in-asp-net-core-web-api/
public class FileUploadOperation : IOperationFilter
{
public void Apply(Operation operation, OperationFilterContext context)
{
if (operation.OperationId.ToLower() == "apivaluesuploadpost")
{
operation.Parameters.Clear();
operation.Parameters.Add(new NonBodyParameter
{
Name = "uploadedFile",
In = "formData",
Description = "Upload File",
Required = true,
Type = "file"
});
operation.Consumes.Add("multipart/form-data");
}
}
}
然后,在services.ConfigureSwaggerGen()参数中,添加
options.OperationFilter<FileUploadOperation>();
方法的原理是通过重写操作某个特定API的的过滤器,来实现对返回内容的操作。
此方法适用于OAS2,实质上是实现了这里的规范要求。
我已经用上.NET 5.0了,自带了swagger都支持的是OpenAPI 3,这个方法不好用了。不过思想应该相同,首先看看OpenAPI 3的规范,文件上传需要定义为:
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
fileName:
type: string
format: binary
这个套路和OpenAPI 2完全不一样,需要重新设置requestBody才行。我们按照要求改造代码。
public class FileUploadOperation : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
//判断上传文件的类型,只有上传的类型是IFormCollection的才进行重写。
if (context.ApiDescription.ActionDescriptor.Parameters.Any(w => w.ParameterType == typeof(IFormCollection)))
{
Dictionary<string, OpenApiSchema> schema = new Dictionary<string, OpenApiSchema>();
schema["fileName"] = new OpenApiSchema { Description = "Select file", Type = "string", Format = "binary" };
Dictionary<string, OpenApiMediaType> content = new Dictionary<string, OpenApiMediaType>();
content["multipart/form-data"] = new OpenApiMediaType { Schema = new OpenApiSchema { Type = "object", Properties = schema } };
operation.RequestBody = new OpenApiRequestBody() { Content = content };
}
}
}
执行之后,swagger已经可以正常识别了,通过选择文件即可上传,效果如下:

参考资料
- https://docs.microsoft.com/en-us/aspnet/core/tutorials/getting-started-with-swashbuckle?view=aspnetcore-5.0&tabs=visual-studio
- https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads?view=aspnetcore-5.0#upload-large-files-with-streaming
- https://www.talkingdotnet.com/how-to-upload-file-via-swagger-in-asp-net-core-web-api/
使用swagger上传文件的更多相关文章
- .Net Core小技巧 - 使用Swagger上传文件
前言 随着前后端分离开发模式的普及,后端人员更多是编写服务端API接口.调用接口实现文件上传是一个常见的功能,同时也需要一个选择文件上传的界面,可以编写前端界面上传,可以使用Postman.curl来 ...
- swagger上传文件并支持jwt认证
背景 由于swagger不仅提供了自动实现接口文档的说明而且支持页面调试,告别postman等工具,无需开发人员手动写api文档,缩减开发成本得到大家广泛认可 但是由于swagger没有提供上传文件的 ...
- .Net core3.0 集成swagger5.0上传文件
.Net core 3.0已经更新了,相信有挺多博主大佬们都更新了如何在.Net core3.0使用swagger,这里就不详细说了. 我们知道,如果.net core 2.x使用swagger上传文 ...
- Abp中SwaggerUI的接口文档添加上传文件参数类型
在使用Swashbuckle上传文件的时候,在接口文档中希望看到上传控件,但是C#中,没有FromBodyAttribute这个特性,所以需要在运行时,修改参数的swagger属性. 首先看下,最 ...
- .NET CORE上传文件到码云仓库【搭建自己的图床】
.NET CORE上传文件到码云仓库[搭建自己的图床] 先建一个公共仓库(随意提交一个README文件或者.gitignore文件保证master分支的存在),然后到gitee的个人设置页面找到[私人 ...
- SpringMvc通过controller上传文件代码示例
上传文件这个功能用的比较多,不难,但是每次写都很别扭.记录在此,以备以后copy用. package com.**.**.**.web.api; import io.swagger.annotatio ...
- Aliyun Oss 上传文件
目录 Aliyun OSS OSS 简介 OSS 基本概念 OSS 功能概述 OSS 使用 创建存储空间Bucket 创建子目录 Java编码 测试 Aliyun OSS OSS 简介 阿里云对象存储 ...
- IE8/9 JQuery.Ajax 上传文件无效
IE8/9 JQuery.Ajax 上传文件有两个限制: 使用 JQuery.Ajax 无法上传文件(因为无法使用 FormData,FormData 是 HTML5 的一个特性,IE8/9 不支持) ...
- 三种上传文件不刷新页面的方法讨论:iframe/FormData/FileReader
发请求有两种方式,一种是用ajax,另一种是用form提交,默认的form提交如果不做处理的话,会使页面重定向.以一个简单的demo做说明: html如下所示,请求的路径action为"up ...
随机推荐
- Zuul 超时设置
问题描述 使用 Zuul 作为网关,偶发超时问题及第一次调用触发熔断问题 解决方案 超时问题 ribbon: ReadTimeout: 10000 SocketTimeout: 60000 第一次调用 ...
- cf div2 round 688 题解
爆零了,自闭了 小张做项目入职字节 小李ak wf入职ms 我比赛爆零月薪3k 我们都有光明的前途 好吧,这场感觉有一点难了,昨天差点卡死在B上,要不受O爷出手相救我就boom zero了 第一题,看 ...
- 如何利用小熊派获取MPU6050六轴原始数据
摘要:使用小熊派开发板,通过硬件IIC与MPU6050六轴传感器模块通信,完成相应寄存器配置,成功获取陀螺仪.加速度计数据. 本问主要讲述使用小熊派开发板+MPU6050六轴传感器,获取加速度计以及陀 ...
- 老猿学5G:融合计费基于流计费的触发器Triggers
☞ ░ 前往老猿Python博文目录 ░ 一.概述 每个触发条件都是一个可计费事件.SMF中的功能体CTF在用户上网时达到一定条件就会向CHF上报流量,而CTF什么时候触发流量上报是由CTF中的触发器 ...
- PyQt(Python+Qt)学习随笔:MoviePy视频转GIF动图相关方法介绍
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 MoviePy能处理的视频是ffmpeg格式的,老猿理解支持的文件类型 ...
- PyQt(Python+Qt)学习随笔:QMainWindow的setDockNestingEnabled作用案例图解
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 QMainWindow的setDockNestingEnabled的作 ...
- 第11.27节 Python正则小结:正则静,静则明,明则虚,虚则无为而无不为也
正则表达式的章节到此就结束了,老猿现在觉得对我们这些身具程序猿基因特色的人来说,正则表达式应该是蛮可口的开胃小菜. 在写标题时,本来想写"正则表达式小结",后来想了想,百度了一下, ...
- 第14.4节 使用IE浏览器获取网站访问的http信息
上节<第14.3节 使用google浏览器获取网站访问的http信息>中介绍了使用Google浏览器怎么获取网站访问的http相关报文信息,本节介绍IE浏览器中怎么获取相关信息.以上节为基 ...
- CSS图标与文字对齐的两种方法
在平时写页面的过程中,常遇到要把小图标与文字对齐的情况.比如: 总结了两种方法,代码量都比较少. 第一种 对img设置竖直方向对齐为middle, <div> <img src=&q ...
- 查询满足条件的最新数据(逐步优化,mysql、达梦数据库)
1.条件:报警信息表sensor_warning 2.需求: 查询当前车厢的.不同设备的.所有处理未完成的.不同报警原因的.时间最新的数据集合,最后按设备id或报警时间排序 3.原始sql,不满足实际 ...