前言

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

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

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

   /// <summary>
/// 文件模型
/// </summary>
public class FileModel
{
/// <summary>
/// 文件名称
/// </summary>
public string FileName { get; set; }
/// <summary>
/// 文件类型,如jpg,doc
/// </summary>
[Required(ErrorMessage = "{0}不能为空")]
public string FileType { get; set; }
/// <summary>
/// base64字符串
/// </summary>
[Required(ErrorMessage="{0}不能为空")]
public string FileStr { get; set; } }

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

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

         /// <summary>
/// 使用base64字符串上传文件(图片)
/// </summary>
/// <param name="model">文件模型</param>
/// <returns>ResultInfo</returns>
[HttpPost]
[Swashbuckle.Swagger.Annotations.SwaggerResponse(HttpStatusCode.OK, Type = typeof(ResultInfo<string>))]
public HttpResponseMessage PostFromBase64Str([FromBody]FileModel model)
{
ResultInfo<string> result = new ResultInfo<string>();
try
{
string folderPath = System.Web.HttpContext.Current.Server.MapPath(@"/Upload/ApiFile/");
//判断项目路径是否存在
if (!System.IO.Directory.Exists(folderPath))
{
System.IO.Directory.CreateDirectory(folderPath);
}
//生成GUID文件名
string fileName = System.Guid.NewGuid().ToString().Replace("-", "") + "." + model.FileType; //读取字符串转为字节数组
byte[] strs = Convert.FromBase64String(model.FileStr);
//文件保存路径
string filePath = folderPath + fileName;
using (System.IO.FileStream fs = new System.IO.FileStream(filePath,FileMode.OpenOrCreate,FileAccess.Write))
{
//保存文件
fs.WriteAsync(strs, , strs.Length);
}
}
catch (Exception ex)
{
result.Status = "FAIL";
result.Msg = ex.Message;
}
return toJson<string>(result);
}

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

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

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

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

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

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

PostFromFormData 方法代码如下:

         /// <summary>
/// 使用form表单上传文件
/// </summary>
/// <returns>ResultInfo</returns>
[HttpPost]
[Swashbuckle.Swagger.Annotations.SwaggerResponse(HttpStatusCode.OK, Type = typeof(ResultInfo<string>))]
public HttpResponseMessage PostFromFormData()
{
ResultInfo<string> result = new ResultInfo<string>();
try
{
var rq = System.Web.HttpContext.Current.Request;
//这里跟前端调用或调用方 协商好,请求的content 类型必须为multipart/form-data
if (!rq.ContentType.Contains("multipart"))
{
result.Status = "FAIL";
return toJson<string>(result);
}
//读取表单数据,若是有其他参数,可以约定好统一放到form中,如Token,timestamp
var form = rq.Form;
//获取上传的文件集合,可能上传了多个文件
var files = rq.Files;
var count = files.Count;//获取文件的数量
var fileExtention = "";//文件的扩展名
if (count > )
{
// 在遍历文件前,需验证form上传的参数
//在实际项目中,常常需要做一些基础参数的验证
//if (!form.AllKeys.Contains("Token")) //若form没有添加Token参数,直接返回
//{
// result.Status = "FAIL";
// return toJson<string>(result);
//}
//遍历所有的文件
for (int i = ; i < count; i++)
{
var file = files[i];
var fileName = file.FileName;
var fileType = file.ContentType;//文件类型
//
fileExtention = fileName.Split('.')[];
//读取文件的二进制流
var itemStream = file.InputStream;
var filePath = "";//存储返回路径 在实际项目中,数据库存储的是相对路径,方便更换服务器。
bool back = SaveFileFromStream(itemStream, fileExtention, out filePath);
if (!back)
{
result.Status = "FAIL";
result.Msg = "UploadFail";
}
}
}
else
{
//使用二进制上传文件
var stream = rq.InputStream;
} }
catch (Exception ex)
{
result.Status = "FAIL";
result.Msg = ex.Message;
}
return toJson<string>(result);
}

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

这样,只要完成以上两个方法就可以通过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!

补记

最近,ios、android 同事在调用这个接口的时候,发现,只有一个文件的时候,调用是成功。多个文件,就只接收到一个文件。后来发现,是他们上传的格式有问题。因此,大家在提供这个接口给第三方调用的是,务必按以下的

文件格式上传:

.POST /api/FriendDiary/PostFile HTTP/1.1
Content-Type: multipart/form-data; boundary=--------------------------
Host: 120.24.246.194:
content-length: ----------------------------
Content-Disposition: form-data; name="UserId" ----------------------------
Content-Disposition: form-data; name="Token" ----------------------------
Content-Disposition: form-data; name="Timestamp" wwww
----------------------------
Content-Disposition: form-data; name="RecordId" ----------------------------
Content-Disposition: form-data; name=""; filename="............_20170915173117.png"
Content-Type: image/png 文件流
------------------------------ .

各个参数间,都是由边界相隔的。同时,每个参数行后面都是一个回车。APP部门同事上传多个文件之所以没有成功,就是在拼接第二个文件流的时候,少了回车。

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

  1. Spring MVC实现文件上传

    基础准备: Spring MVC为文件上传提供了直接支持,这种支持来自于MultipartResolver.Spring使用Jakarta Commons FileUpload技术实现了一个Multi ...

  2. MVC之文件上传1

    MVC之文件上传 前言 这一节我们来讲讲在MVC中如何进行文件的上传,我们逐步深入,一起来看看. Upload File(一) 我们在默认创建的项目中的Home控制器下添加如下: public Act ...

  3. Asp.net mvc 大文件上传 断点续传

    Asp.net mvc 大文件上传 断点续传 进度条   概述 项目中需要一个上传200M-500M的文件大小的功能,需要断点续传.上传性能稳定.突破asp.net上传限制.一开始看到51CTO上的这 ...

  4. Spring MVC的文件上传

    1.文件上传 文件上传是项目开发中常用的功能.为了能上传文件,必须将表单的method设置为POST,并将enctype设置为multipart/form-data.只有在这种情况下,浏览器才会把用户 ...

  5. Spring MVC的文件上传和下载

    简介: Spring MVC为文件上传提供了直接的支持,这种支持使用即插即用的MultipartResolver实现的.Spring MVC 使用Apache Commons FileUpload技术 ...

  6. 整合MVC实现文件上传

    1.整合MVC实现文件上传整合MVC实现文件上传在实际的开发中在实现文件上传的同时肯定还有其他信息需要保存到数据库,文件上传完毕之后需要将提交的基本信息插入数据库,那么我们来实现这个操作.整个MVC实 ...

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

    作者:ssslinppp       1. 摘要 Spring MVC为文件上传提供了最直接的支持,这种支持是通过即插即用的MultipartResolve实现的.Spring使用Jakarta Co ...

  8. MVC图片上传、浏览、删除 ASP.NET MVC之文件上传【一】(八) ASP.NET MVC 图片上传到服务器

    MVC图片上传.浏览.删除   1.存储配置信息 在web.config中,添加配置信息节点 <appSettings> <add key="UploadPath" ...

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

    问题:使用spring mvc ajaxfileupload 文件上传在ie8下会提示json下载问题 解决方案如下: 服务器代码: @RequestMapping(value = "/ad ...

随机推荐

  1. java操作properties配置文件

    Java中有个类Properties(Java.util.Properties),主要用于读取Java的配置文件,将一些可能需要变化的值存放在properties中进行配置,通常为为.properti ...

  2. Java并发框架——AQS超时机制

    AQS框架提供的另外一个优秀机制是锁获取超时的支持,当大量线程对某一锁竞争时可能导致某些线程在很长一段时间都获取不了锁,在某些场景下可能希望如果线程在一段时间内不能成功获取锁就取消对该锁的等待以提高性 ...

  3. Quick-Cocos2d-X 捋一捋框架流程

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=535 一直比较关注Quick L ...

  4. iOS中 为 iOS 建立 Travis CI 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博! 你是否曾经试着为 iOS 项目搭建一台支持持续集成的服务器,从我的个人经验而言,这可不是一个轻松的活.首先需要准备 ...

  5. Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(六)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 在Xcode中打开MainScene.h文件,在接口中添加2个方 ...

  6. 用SpriteBuilder简化"耕牛遍地走"的动画效果(一)

    这又是一个使用SpriteBuilder带来便捷的例子 原文地址在: http://www.raywenderlich.com/32045/how-to-use-animations-and-spri ...

  7. React Native的WebStorm基本设置

    jsx语法设置 在没有进行设置的情况下,每次打开WebStorm的时候打开包含jsx语法的.js文件都会有以下提示: 当然我们点击转换后就可以了,但是每次都会提示,所以还是来一个一劳永逸的方法把它给去 ...

  8. Github最流行的10,000个Java项目使用的类库

    本文由 ImportNew - Andy.Song 翻译自 takipiblog.欢迎加入翻译小组.转载请见文末要求. 前言 作为Java开发人员,总是需要面临这门不断成熟.高速改进中的语言.开发人员 ...

  9. Java之谜 —— 来自Neal Gafter的演讲

    翻译人员: 铁锚 翻译日期: 2013年11月20日 原文链接: A Puzzle from "A Brief History of the (Java) World and a Peek ...

  10. 使用Libgdx开发的FlappyBird(像素鸟、疯狂的小鸟)游戏源码

    本帖最后由 宋志辉 于 2014-10-21 15:06 编辑 点击进入下载地址 Flappy Bird(飞扬的小鸟)由一位来自越南河内的独立游戏开发者阮哈东开发,是一款形式简易但难度极高的休闲游戏. ...