IT轮子系列(五)——MVC API 文件上传,总有一款是你需要的

前言

在对外提供的接口时,也常常需要提供上传文件的。在这篇文章中会描述三种上传方式。

1、第一款,通过Base64字符上传——PostFromBase64Str

首先,定义上传数据模型。对于模型的定义,一般都会给定名称、文件类型、数据字段。如下代码所示:

 1   /// <summary>
 2     /// 文件模型
 3     /// </summary>
 4     public class FileModel
 5     {
 6         /// <summary>
 7         /// 文件名称
 8         /// </summary>
 9         public string FileName { get; set; }
10         /// <summary>
11         /// 文件类型,如jpg,doc
12         /// </summary>
13         [Required(ErrorMessage = "{0}不能为空")]
14         public string FileType { get; set; }
15         /// <summary>
16         /// base64字符串
17         /// </summary>
18         [Required(ErrorMessage="{0}不能为空")]
19         public string FileStr { get; set; }
20
21     }

ps:这篇文章也是在介绍swagger使用中使用的解决方案。

其次,在API控制器中定义接收文件的方法

 1         /// <summary>
 2         /// 使用base64字符串上传文件(图片)
 3         /// </summary>
 4         /// <param name="model">文件模型</param>
 5         /// <returns>ResultInfo</returns>
 6         [HttpPost]
 7         [Swashbuckle.Swagger.Annotations.SwaggerResponse(HttpStatusCode.OK, Type = typeof(ResultInfo<string>))]
 8         public HttpResponseMessage PostFromBase64Str([FromBody]FileModel model)
 9         {
10             ResultInfo<string> result = new ResultInfo<string>();
11             try
12             {
13                 string folderPath = System.Web.HttpContext.Current.Server.MapPath(@"/Upload/ApiFile/");
14                 //判断项目路径是否存在
15                 if (!System.IO.Directory.Exists(folderPath))
16                 {
17                     System.IO.Directory.CreateDirectory(folderPath);
18                 }
19                 //生成GUID文件名
20                 string fileName = System.Guid.NewGuid().ToString().Replace("-", "") + "." + model.FileType;
21
22                 //读取字符串转为字节数组
23                 byte[] strs = Convert.FromBase64String(model.FileStr);
24                 //文件保存路径
25                 string filePath = folderPath + fileName;
26                 using (System.IO.FileStream fs = new System.IO.FileStream(filePath,FileMode.OpenOrCreate,FileAccess.Write))
27                 {
28                     //保存文件
29                     fs.WriteAsync(strs, 0, strs.Length);
30                 }
31             }
32             catch (Exception ex)
33             {
34                 result.Status = "FAIL";
35                 result.Msg = ex.Message;
36             }
37             return toJson<string>(result);
38         }

这里要注意的是,有些工具将文件转为BASE64是带格式说明的,如下图:

在实际项目中,这个数据格式要跟前端或者调用方协商好,数据是只传逗号后面部分还是传所有的;如果是所有的,在接收的时候就需要后台处理,把数据截取出来。否则会保存不成功。

好了,第一款,上传文件就这么简单。

第二款,从Form表单上传文件—— PostFromFormData

我们都知道,在form表单中,可以使用input type=file 控件上传文件。在API 中也可以使用这个知识点。

使用这种方法上传,需要了解一个类:System.Web.HttpContext .Current.Request 。今天,在敲代码的时候,发现深入理解并用好这个Request就可以解决大部分请求的问题。建议,设置个断点进去看看它都有那些内容。

PostFromFormData 方法代码如下:

 1         /// <summary>
 2         /// 使用form表单上传文件
 3         /// </summary>
 4         /// <returns>ResultInfo</returns>
 5         [HttpPost]
 6         [Swashbuckle.Swagger.Annotations.SwaggerResponse(HttpStatusCode.OK, Type = typeof(ResultInfo<string>))]
 7         public HttpResponseMessage PostFromFormData()
 8         {
 9             ResultInfo<string> result = new ResultInfo<string>();
10             try
11             {
12                 var rq = System.Web.HttpContext.Current.Request;
13                 //这里跟前端调用或调用方 协商好,请求的content 类型必须为multipart/form-data
14                 if (!rq.ContentType.Contains("multipart"))
15                 {
16                     result.Status = "FAIL";
17                     return toJson<string>(result);
18                 }
19                 //读取表单数据,若是有其他参数,可以约定好统一放到form中,如Token,timestamp
20                 var form = rq.Form;
21                 //获取上传的文件集合,可能上传了多个文件
22                 var files = rq.Files;
23                 var count = files.Count;//获取文件的数量
24                 var fileExtention = "";//文件的扩展名
25                 if (count > 0)
26                 {
27                     // 在遍历文件前,需验证form上传的参数
28                     //在实际项目中,常常需要做一些基础参数的验证
29                     //if (!form.AllKeys.Contains("Token")) //若form没有添加Token参数,直接返回
30                     //{
31                     //    result.Status = "FAIL";
32                     //    return toJson<string>(result);
33                     //}
34                     //遍历所有的文件
35                     for (int i = 0; i < count; i++)
36                     {
37                         var file = files[i];
38                         var fileName = file.FileName;
39                         var fileType = file.ContentType;//文件类型
40                         //
41                         fileExtention = fileName.Split(‘.‘)[1];
42                         //读取文件的二进制流
43                         var itemStream = file.InputStream;
44                         var filePath = "";//存储返回路径  在实际项目中,数据库存储的是相对路径,方便更换服务器。
45                         bool back = SaveFileFromStream(itemStream, fileExtention, out filePath);
46                         if (!back)
47                         {
48                             result.Status = "FAIL";
49                             result.Msg = "UploadFail";
50                         }
51                     }
52                 }
53                 else
54                 {
55                     //使用二进制上传文件
56                     var stream = rq.InputStream;
57                 }
58
59             }
60             catch (Exception ex)
61             {
62                 result.Status = "FAIL";
63                 result.Msg = ex.Message;
64             }
65             return toJson<string>(result);
66         }

其中,保存文件的私有方法如下:

这样,只要完成以上两个方法就可以通过form表单上传文件拉。

PS:因为要测试文件的上传,暂时不懂如何配置swagger,让它支持上传文件。在这里,推荐使用Postman(网上自行下载安装) 进行测试。如下图所示:

1、设定请求地址以及请求内容

2、设定请求的数据,如下图:

这样,当我们点击发送之后,就能看到返回OK的结果。同时,在我们网站的目录,会看到上传成功的文件,如下图:

第三款,使用二进制Binary上传文件

从上面的方法PostFromFormData中就可以看到,count>0的分支,就是使用二进制上传的文件。其中的原理跟form表单是一样的,都是通过Inputstream。

这里面要注意的是,因为使用binary上传的时候,没法定义form表单数据。因此,需要在请求headers中添加参数。如协商好的文件类型等。

代码如下:

运行项目,启动postman,进行测试:

1、配置请求头

2、修改body 为Binay

点击发送,同样可以看到OK返回。在文件夹目录下也可看到新上传的文件:

总结

以上,就是通过API上传文件的三款方式,希望可以帮助到大家。在测试的时候,只是上传了图片。其实,在form表单上传中并不只限于图片,比如也可上传doc,txt等。因为都是通过inputstream保存文件,同时,其上传大文件类型也是可以知道的,因此,form表单这种方式是通用的。

PS:上传文件,应该还涉及到大文件的断点续传,不过在实际项目还没有碰到过断点需求这样的需求,这里就不作描述了。

大家,GOOD NIGTH!

时间: 2024-08-03 15:07:33

IT轮子系列(五)——MVC API 文件上传,总有一款是你需要的的相关文章

ios网络学习------11 原生API文件上传之断点续传思路

#import "MainViewController.h" @interface MainViewController () @end @implementation MainViewController - (void)viewDidLoad { [super viewDidLoad]; //下载文件 [self download]; } -(void)download { //1. NSURL NSURL *url = [NSURL URLWithString:@"ht

Spring MVC 多文件上传大小限制及异常处理

Spring MVC  多文件上传大小限制及异常处理 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS.Android.Html5.Arduino.pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 在 spring mvc 的默认配置文件 WEB-INF/xxx-servlet.xml 中

MVC之文件上传1

MVC之文件上传 前言 这一节我们来讲讲在MVC中如何进行文件的上传,我们逐步深入,一起来看看. Upload File(一) 我们在默认创建的项目中的Home控制器下添加如下: public ActionResult UploadFile() { return View(); } [HttpPost] public ActionResult UploadFile(HttpPostedFileBase file) { var fileName = file.FileName; var fileP

【Spring学习笔记-MVC-13】Spring MVC之文件上传

作者:ssslinppp       1. 摘要 Spring MVC为文件上传提供了最直接的支持,这种支持是通过即插即用的MultipartResolve实现的.Spring使用Jakarta Commons FileUpload技术实现了一个MultipartResolver实现类:CommonsMultipartResolver. 下面将具体讲解Spring MVC实现文件上传的具体步骤. 2. 添加Jar包 Spring MVC文件上传,需要添加如下两个jar包: commons-fil

spring mvc ajaxfileupload文件上传返回json下载问题

问题:使用spring mvc ajaxfileupload 文件上传在ie8下会提示json下载问题 解决方案如下: 服务器代码: @RequestMapping(value = "/addAnalysis", method = RequestMethod.POST) public void addAnalysisUI( HttpServletResponse response,HttpServletRequest request,HttpSession session, @Requ

IT轮子系列(六)——Excel上传与解析,一套代码解决所有Excel业务上传,你Get到了吗

前言 在日常开发当中,excel的上传与解析是很常见的.根据业务不同,解析的数据模型也都不一样.不同的数据模型也就需要不同的校验逻辑,这往往需要写多套的代码进行字段的检验,如必填项,数据格式.为了避免重复编写逻辑检验代码,于是有了这篇文章. 第一步.读取Excel表格数据 1 public ActionResult UploadExcel() 2 { 3 ResultInfo<List<User>> result = new ResultInfo<List<User&g

Spring MVC实现文件上传和下载

本篇博客将讲解的是Springmvc的文件上传和下载功能.对于上传功能,我们在项目中是经常会用到的,比如用户注册的时候,上传用户头像,这个时候就会使用到上传的功能.而对于下载,使用场景也很常见,比如我们项目中有个使用说明是是pdf版的,会提供给用户进行下载的功能.相对于来说,这两个功能都是很常见,废话不多说,按照惯例,我们先来看一下本篇博客的目录. 目录 一:搭建SpringMvc开发环境 二:实现文件上传的功能 三:将上传文件绑定到具体的对象上 四 : 实现用户下载的功能 五:总结 一:搭建S

用VSCode开发一个asp.net core2.0+angular5项目(5): Angular5+asp.net core 2.0 web api文件上传

第一部分: http://www.cnblogs.com/cgzl/p/8478993.html 第二部分: http://www.cnblogs.com/cgzl/p/8481825.html 第三部分: https://www.cnblogs.com/cgzl/p/8525541.html 第四部分: https://www.cnblogs.com/cgzl/p/8536350.html 这部分就讲从angular5的客户端上传图片到asp.net core 2.0的 web api. 这是

MVC实现文件上传

不考虑细节,只实现简单的文件上传操作 一 引入common-fileupload.jar和common-io.jar文件 二 在SprinMVC核心配置文件中配置解析器 <!-- 配置文件上传 --> <bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver"> <!-- 解决文件名的中文乱