《打造一个网站或者其他网络应用的文件管理接口(WebApi)第二章“多文件上传”》

========================================================
作者:qiujuer
博客:blog.csdn.net/qiujuer
网站:www.qiujuer.net
开源库:Genius-Android
转载请注明出处:http://blog.csdn.net/qiujuer/article/details/41675299
========================================================

History

[WebApi] 捣鼓一个资源管理器--文件下载

In This

既然访问文件接口有了,怎么能少的了文件的上传接口呢!

既然是文件上传接口那就肯定要来一个猛一点的接口--多文件上传

CodeTime

改动

进入正题前先来看看本次改动的文件有哪些:

可以看见一共有4个文件进行了改动,其中Home与ResourceApi是添加了方法,Model/Resource是新增,View/Upload也是新增。

Model部分

为了返回数据简单方便,所以New 了一个类 Resource.cs

namespace WebResource.Models
{public class Resource{public string Id { get; set; }public string Type { get; set; }}
}

If Easy?

ResourceApi 部分

然后来看看咱们的ResourceApi类:

namespace WebResource.Controllers
{[RoutePrefix("Resource")]public class ResourceApiController : ApiController{private static readonly long MEMORY_SIZE = 64 * 1024 * 1024;private static readonly string ROOT_PATH = HttpContext.Current.Server.MapPath("~/App_Data/");[HttpGet][Route("{Id}")]public async Task<HttpResponseMessage> Get(string Id){// 进入时判断当前请求中是否含有 ETag 标识,如果有就返回使用浏览器缓存// Return 304var tag = Request.Headers.IfNoneMatch.FirstOrDefault();if (Request.Headers.IfModifiedSince.HasValue && tag != null && tag.Tag.Length > 0)return new HttpResponseMessage(HttpStatusCode.NotModified);// 进行模拟 App_Data/Image/{id}.png// 打开找到文件FileInfo info = new FileInfo(Path.Combine(ROOT_PATH, "Image", Id + ".png"));if (!info.Exists)return new HttpResponseMessage(HttpStatusCode.BadRequest);FileStream file = null;try{// 打开文件file = new FileStream(info.FullName, FileMode.Open, FileAccess.Read, FileShare.Read);HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);// 在浏览器中显示 inlineContentDispositionHeaderValue disposition = new ContentDispositionHeaderValue("inline");// 写入文件基本信息disposition.FileName = file.Name;disposition.Name = file.Name;disposition.Size = file.Length;// 判断是否大于64Md,如果大于就采用分段流返回,否则直接返回if (file.Length < MEMORY_SIZE){//Copy To Memory And Close.byte[] bytes = new byte[file.Length];await file.ReadAsync(bytes, 0, (int)file.Length);file.Close();MemoryStream ms = new MemoryStream(bytes);result.Content = new ByteArrayContent(ms.ToArray());}else{result.Content = new StreamContent(file);}// 写入文件类型,这里是图片pngresult.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png");result.Content.Headers.ContentDisposition = disposition;// 设置缓存信息,该部分可以没有,该部分主要是用于与开始部分结合以便浏览器使用304缓存// Set Cacheresult.Content.Headers.Expires = new DateTimeOffset(DateTime.Now).AddHours(1);// 这里应该写入文件的存储日期result.Content.Headers.LastModified = new DateTimeOffset(DateTime.Now);result.Headers.CacheControl = new CacheControlHeaderValue() { Public = true, MaxAge = TimeSpan.FromHours(1) };// 设置Etag,这里就简单采用 Idresult.Headers.ETag = new EntityTagHeaderValue(string.Format("\"{0}\"", Id));// 返回请求return result;}catch{if (file != null){file.Close();}}return new HttpResponseMessage(HttpStatusCode.BadRequest);}[HttpPost][Route("Upload")][ResponseType(typeof(Resource))]public async Task<IHttpActionResult> Post(){List<Resource> resources = new List<Resource>();// multipart/form-data// 采用MultipartMemoryStreamProvidervar provider = new MultipartMemoryStreamProvider();//读取文件数据await Request.Content.ReadAsMultipartAsync(provider);foreach (var item in provider.Contents){// 判断是否是文件if (item.Headers.ContentDisposition.FileName != null){//获取到流var ms = item.ReadAsStreamAsync().Result;//进行流操作using (var br = new BinaryReader(ms)){if (ms.Length <= 0)break;//读取文件内容到内存中var data = br.ReadBytes((int)ms.Length);//Create//当前时间作为IDResource resource = new Resource() { Id = DateTime.Now.ToString("yyyyMMddHHmmssffff", DateTimeFormatInfo.InvariantInfo) };//InfoFileInfo info = new FileInfo(item.Headers.ContentDisposition.FileName.Replace("\"", ""));//文件类型resource.Type = info.Extension.Substring(1).ToLower();//Writetry{//文件存储地址string dirPath = Path.Combine(ROOT_PATH);if (!Directory.Exists(dirPath)){Directory.CreateDirectory(dirPath);}File.WriteAllBytes(Path.Combine(dirPath, resource.Id), data);resources.Add(resource);}catch { }}}}//返回if (resources.Count == 0)return BadRequest();else if (resources.Count == 1)return Ok(resources.FirstOrDefault());elsereturn Ok(resources);}}
}

与上一章比较看来,只是增加了一个方法 Post ,而后将其重定向为 Resource/Upload 

其中主要干了些什么我都在方法中注明了;应该是足够简单的。

现在运行一下,看看我们的Api是怎样的:


下面我们来调用它试试。

HomeController部分

修改HomeController 添加一个Upload 方法:

namespace WebResource.Controllers
{public class HomeController : Controller{public ActionResult Index(){ViewBag.Title = "Home Page";return View();}public ActionResult Upload(){return View();}}
}
Upload.cshtml部分

而后在方法上点击右键添加视图,然后进入 View/Home/Upload.cshtml 视图中修改为:

@{ViewBag.Title = "Upload";
}<h2>Upload</h2><div id="body"><h1>多文件上传模式</h1><section class="main-content clear-fix"><form name="form1" method="post" enctype="multipart/form-data" action="/Resource/Upload"><fieldset><legend>File Upload Example</legend><div><label for="caption">File1</label><input name="file1" type="file" /></div><div><label for="image1">File2</label><input name="file2" type="file" /></div><div><input type="submit" value="Submit" /></div></fieldset></form></section>
</div>

在该视图中,我们建立了一个 Form 表单,然后指定为 Post 模式;同时指定

enctype="multipart/form-data" action="/Resource/Upload"

RunTime

写完了代码当然是调试运行喽!

运行 localhost:60586/Home/Upload
这里我们添加文件,还是使用上一章中的两种图片吧:


运行后:

当然,这里是因为我的浏览器是谷歌浏览器,所以返回的是 XML 数据,如果你的事IE浏览器那么应该返回的是Json 文件。

WebApi会根据请求返回不同的数据。

可以看到,现在 App_Data文件夹下,多了两个文件了;不过这两个文件是没有加上文件类型的;你可以手动给他加上个.png 然后打开看看是不是那两张图片。

END

OK,这一章就到此为止了!

资源文件

第一章资源文件(说好了这章中添加)

第二章资源文件

下一章

下一章将会把上传与下载查看两个方法相互结合,搭配起来;同时将会结合数据进行辅助存储文件信息。

同时,会讲如何避免文件重复上传的问题。

已更新:[WebApi] 捣鼓一个资源管理器--多文件上传+数据库辅助

========================================================
作者:qiujuer
博客:blog.csdn.net/qiujuer
网站:www.qiujuer.net
开源库:Genius-Android
转载请注明出处:http://blog.csdn.net/qiujuer/article/details/41675299
========================================================

[WebApi] 捣鼓一个资源管理器--多文件上传相关推荐

  1. 管理springmvc组件——前端控制器、控制器映射器和适配器、视图解析器、文件上传的、拦截器||消息转化

    管理springmvc组件 概述 在使用springmvc时要配置哪些东西 前端控制器 控制器映射器和适配器 映射器  Map<Set<String>,Object> Set& ...

  2. Spring Boot(5) web开发(3)拦截器、文件上传、异常处理

    Spring Boot(5) web开发(3)拦截器.文件上传.异常处理 学习视频: https://www.bilibili.com/video/BV19K4y1L7MT?p=49&spm_ ...

  3. SSM之SpringMVC 04 —— Ajax、拦截器、文件上传和下载

    系列文章 SSM之SpringMVC 01 -- SpringMVC原理及概念.Hello SpringMVC 注解版和配置版 SSM之SpringMVC 02 -- Controller和RestF ...

  4. WebApi发送HTML表单数据:文件上传与多部分MIME

    5.3 Sending HTML Form Data 5.3 发送HTML表单数据(2) 本文引自:http://www.cnblogs.com/r01cn/archive/2012/12/20/28 ...

  5. Struts2_3_国际化处理_自定义拦截器_文件上传及下载_OGNL

    Struts2国际化处理 浏览器根据当前的语言环境自动查找对应的语言环境资源包, 使jsp显示合适的语言数据环境 Struts2实现国际化, 动作类必须继承ActionSupport 创建资源包 资源 ...

  6. SpringBoot-拦截器和文件上传

    1.拦截器 1.1.HandlerInterceptor 接口 /*** 登录检查* 1.配置好拦截器要拦截哪些请求* 2.把这些配置放在容器中*/ @Slf4j public class Login ...

  7. Springboot2拦截器与文件上传

    拦截器-登录检查与静态资源放行 1.编写一个拦截器实现HandlerInterceptor接口 2.拦截器注册到容器中(实现WebMvcConfigurer的addInterceptors()) 3. ...

  8. (转)WebApi发送HTML表单数据:文件上传与多部分MIME

    5.3 Sending HTML Form Data 5.3 发送HTML表单数据(2) 本文引自:http://www.cnblogs.com/r01cn/archive/2012/12/20/28 ...

  9. SpringMVC之拦截器和文件上传下载

    过滤器与拦截器的区别:拦截器是AOP思想的具体应用. 过滤器 : servlet规范中的一部分,任何java web工程都可以使用 在url-pattern中配置了/*之后,可以对所有要访问的资源进行 ...

  10. SpringMVC学习总结(三):转发重定向、拦截器、文件上传等

    转发和重定向 当Controller中方法的返回值为字符串时,默认为视图名称.当返回值字符串以"forward:"或者"redirect:"开头,则会被认为是转 ...

最新文章

  1. 滴滴自动驾驶获得江苏省苏州公安局颁发的路测牌照
  2. interrupt InterruptException
  3. python的闭包及装饰器
  4. lua编程简单实用入门教程,用NodeMCU在OLED上显示温湿度
  5. TypeError系列之:TypeError: 'tuple' object is not callable.
  6. RabbitMQ 关键词解释
  7. Android Handler机制分析
  8. 【免费毕设】PHP校园二手信息网站的设计与开发(源代码+论文)
  9. Github Star 4.6K,3.5M超超轻量中英文OCR模型开源,火了!
  10. UI之CALayer详解(转)
  11. 第八章《Unity游戏优化》内存管理
  12. 数字形式转换,输入0123456789对应输出“一二三四五六七八九”
  13. 零数开放许可链入选《互联网周刊》2021区块链应用创新TOP50
  14. LeeCode(C++):买卖股票的最佳时机
  15. CO BW成本报表建立小结
  16. GIMP 快速入门(2)
  17. 以太网与 TCP/IP
  18. 下午三点半,公司空空荡荡
  19. 【抓包】- Fiddle软件异常错误,Fiddler Failed to register Fiddler as the system proxy,解决方法
  20. echarts 坐标自适应,实现 ECharts 图表自适应

热门文章

  1. 基于python快速实现排列组合算法
  2. 【Gym-100513 K】Treeland【bfs序构造】
  3. BlackMamba:C2后渗透框架
  4. mysql 存储引擎文件夹_4种常用MySQL存储引擎
  5. [置顶] 话说你最拼命的时候怎样拼命的?
  6. 3、SpringBoot集成Storm WorldCount
  7. Swift 可选(Optionals)类型
  8. [CF888G] Xor-mst (Trie 树,最小生成树)
  9. [您有新的未分配科技点][BZOJ3545BZOJ3551]克鲁斯卡尔重构树
  10. 第三部分数据结构[专业课考试3]