WebApi2 文件图片上传下载
Asp.Net Framework webapi2 文件上传与下载 前端界面采用Ajax的方式执行
一、项目结构

1.App_Start配置了跨域访问,以免请求时候因跨域问题不能提交。具体的跨域配置方式如下,了解的朋友请自行略过。
跨域配置:NewGet安装dll Microsofg.AspNet.Cors

然后在App_Start 文件夹下的WebApiConfig.cs中写入跨域配置代码。
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
// Web API configuration and services
//跨域配置 //need reference from nuget
config.EnableCors(new EnableCorsAttribute("*", "*", "*"));
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
//if config the global filter input there need not write the attributes
//config.Filters.Add(new App.WebApi.Filters.ExceptionAttribute_DG());
}
}
跨域就算完成了,请自行测试。
2.新建两个控制器,一个PicturesController.cs,一个FilesController.cs当然图片也是文件,这里图片和文件以不同的方式处理的,因为图片的方式文件上传没有成功,所以另寻他路,如果在座的有更好的方式,请不吝赐教!
二、项目代码
1.我们先说图片上传、下载控制器接口,这里其实没什么好说的,就一个Get获取文件,参数是文件全名;Post上传文件;直接上代码。
using QX_Frame.App.WebApi;
using QX_Frame.FilesCenter.Helper;
using QX_Frame.Helper_DG;
using QX_Frame.Helper_DG.Extends;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;
/**
* author:qixiao
* create:2017-5-26 16:54:46
* */
namespace QX_Frame.FilesCenter.Controllers
{
public class PicturesController : WebApiControllerBase
{
//Get : api/Pictures
public HttpResponseMessage Get(string fileName)
{
HttpResponseMessage result = null;
DirectoryInfo directoryInfo = new DirectoryInfo(IO_Helper_DG.RootPath_MVC + @"Files/Pictures");
FileInfo foundFileInfo = directoryInfo.GetFiles().Where(x => x.Name == fileName).FirstOrDefault();
if (foundFileInfo != null)
{
FileStream fs = new FileStream(foundFileInfo.FullName, FileMode.Open);
result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StreamContent(fs);
result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = foundFileInfo.Name;
}
else
{
result = new HttpResponseMessage(HttpStatusCode.NotFound);
}
return result;
}
//POST : api/Pictures
public async Task<IHttpActionResult> Post()
{
if (!Request.Content.IsMimeMultipartContent())
{
);
}
string root = IO_Helper_DG.RootPath_MVC;
IO_Helper_DG.CreateDirectoryIfNotExist(root + "/temp");
var provider = new MultipartFormDataStreamProvider(root + "/temp");
// Read the form data.
await Request.Content.ReadAsMultipartAsync(provider);
List<string> fileNameList = new List<string>();
StringBuilder sb = new StringBuilder();
;
;
// This illustrates how to get the file names.
foreach (MultipartFileData file in provider.FileData)
{
//new folder
string newRoot = root + @"Files/Pictures";
IO_Helper_DG.CreateDirectoryIfNotExist(newRoot);
if (File.Exists(file.LocalFileName))
{
//new fileName
, file.Headers.ContentDisposition.FileName.Length - );
];
string newFullFileName = newRoot + "/" + newFileName;
fileNameList.Add($"Files/Pictures/{newFileName}");
FileInfo fileInfo = new FileInfo(file.LocalFileName);
fileTotalSize += fileInfo.Length;
sb.Append($" #{fileIndex} Uploaded file: {newFileName} ({ fileInfo.Length} bytes)");
fileIndex++;
File.Move(file.LocalFileName, newFullFileName);
Trace.WriteLine("1 file copied , filePath=" + newFullFileName);
}
}
return Json(Return_Helper.Success_Msg_Data_DCount_HttpCode($"{fileNameList.Count} file(s) /{fileTotalSize} bytes uploaded successfully! Details -> {sb.ToString()}", fileNameList, fileNameList.Count));
}
}
}
里面可能有部分代码在Helper帮助类里面写的,其实也仅仅是获取服务器根路径和如果判断文件夹不存在则创建目录,这两个代码的实现如下:
public static string RootPath_MVC
{
get { return System.Web.HttpContext.Current.Server.MapPath("~"); }
}
//create Directory
public static bool CreateDirectoryIfNotExist(string filePath)
{
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
return true;
}
2.文件上传下载接口和图片大同小异。
using QX_Frame.App.WebApi;
using QX_Frame.FilesCenter.Helper;
using QX_Frame.Helper_DG;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
/**
* author:qixiao
* create:2017-5-26 16:54:46
* */
namespace QX_Frame.FilesCenter.Controllers
{
public class FilesController : WebApiControllerBase
{
//Get : api/Files
public HttpResponseMessage Get(string fileName)
{
HttpResponseMessage result = null;
DirectoryInfo directoryInfo = new DirectoryInfo(IO_Helper_DG.RootPath_MVC + @"Files/Files");
FileInfo foundFileInfo = directoryInfo.GetFiles().Where(x => x.Name == fileName).FirstOrDefault();
if (foundFileInfo != null)
{
FileStream fs = new FileStream(foundFileInfo.FullName, FileMode.Open);
result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StreamContent(fs);
result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = foundFileInfo.Name;
}
else
{
result = new HttpResponseMessage(HttpStatusCode.NotFound);
}
return result;
}
//POST : api/Files
public async Task<IHttpActionResult> Post()
{
//get server root physical path
string root = IO_Helper_DG.RootPath_MVC;
//new folder
string newRoot = root + @"Files/Files/";
//check path is exist if not create it
IO_Helper_DG.CreateDirectoryIfNotExist(newRoot);
List<string> fileNameList = new List<string>();
StringBuilder sb = new StringBuilder();
;
;
//get files from request
HttpFileCollection files = HttpContext.Current.Request.Files;
await Task.Run(() =>
{
foreach (var f in files.AllKeys)
{
HttpPostedFile file = files[f];
if (!string.IsNullOrEmpty(file.FileName))
{
string fileLocalFullName = newRoot + file.FileName;
file.SaveAs(fileLocalFullName);
fileNameList.Add($"Files/Files/{file.FileName}");
FileInfo fileInfo = new FileInfo(fileLocalFullName);
fileTotalSize += fileInfo.Length;
sb.Append($" #{fileIndex} Uploaded file: {file.FileName} ({ fileInfo.Length} bytes)");
fileIndex++;
Trace.WriteLine("1 file copied , filePath=" + fileLocalFullName);
}
}
});
return Json(Return_Helper.Success_Msg_Data_DCount_HttpCode($"{fileNameList.Count} file(s) /{fileTotalSize} bytes uploaded successfully! Details -> {sb.ToString()}", fileNameList, fileNameList.Count));
}
}
}
实现了上述两个控制器代码以后,我们需要前端代码来调试对接,代码如下所示。
<!doctype>
<head>
<script src="jquery-3.2.0.min.js"></script>
<!--<script src="jquery-1.11.1.js"></script>-->
<!--<script src="ajaxfileupload.js"></script>-->
<script>
$(document).ready(function () {
var appDomain = "http://localhost:3997/";
$("#btn_fileUpload").click(function () {
/**
* 用ajax方式上传文件 -----------
* */
//-------asp.net webapi fileUpload
//这种方式10kb内小文件没有问题,超出大小会失败
var formData = new FormData($("#uploadForm")[0]);
$.ajax({
url: appDomain + 'api/Files',
type: 'POST',
data: formData,
async: false,
cache: false,
contentType: false,
processData: false,
success: function (data) {
console.log(JSON.stringify(data));
},
error: function (data) {
console.log(JSON.stringify(data));
}
});
//----end asp.net webapi fileUpload
//----.net core webapi fileUpload
// var fileUpload = $("#files").get(0);
// var files = fileUpload.files;
// var data = new FormData();
// for (var i = 0; i < files.length; i++) {
// data.append(files[i].name, files[i]);
// }
// $.ajax({
// type: "POST",
// url: appDomain+'api/Files',
// contentType: false,
// processData: false,
// data: data,
// success: function (data) {
// console.log(JSON.stringify(data));
// },
// error: function () {
// console.log(JSON.stringify(data));
// }
// });
//--------end net core webapi fileUpload
/**
* ajaxfileupload.js 方式上传文件
* */
// $.ajaxFileUpload({
// type: 'post',
// url: appDomain + 'api/Files',
// secureuri: false,
// fileElementId: 'files',
// success: function (data) {
// console.log(JSON.stringify(data));
// },
// error: function () {
// console.log(JSON.stringify(data));
// }
// });
});
//end click
})
</script>
</head>
<title></title>
<body>
<article>
<header>
<h2>article-form</h2>
</header>
<p>
<form action="/" method="post" id="uploadForm" enctype="multipart/form-data">
<input type="file" id="files" name="files" placeholder="file" multiple>file-multiple属性可以选择多项<br><br>
<input type="button" id="btn_fileUpload" value="fileUpload">
</form>
</p>
</article>
</body>
至此,我们的功能已全部实现,下面我们来测试一下:

可见,文件上传成功,按预期格式返回!
下面我们测试单图片上传->

然后我们按返回的地址进行访问图片地址。

发现并无任何压力!
下面测试多图片上传->

完美~
至此,我们已经实现了WebApi2文件和图片上传,下载的全部功能。
WebApi2 文件图片上传下载的更多相关文章
- [iOS AFNetworking框架实现HTTP请求、多文件图片上传下载]
简单的JSON的HTTP传输就不说了,看一个简单的DEMO吧. 主要明白parameters是所填参数,类型是字典型.我把这部分代码封装起来了,以便多次调用.也许写在一起更清楚点. #pragma m ...
- WebUploader文件图片上传插件的使用
最近在项目中用到了百度的文件图片上传插件WebUploader.分享给大家 需要在http://fex.baidu.com/webuploader/download.html点击打开链接下载WebUp ...
- Retrofit 2.0 轻松实现多文件/图片上传/Json字符串/表单
如果嫌麻烦直接可以用我封装好的库:Novate: https://github.com/Tamicer/Novate 通过对Retrofit2.0的前两篇的基础入门和案例实践,掌握了怎么样使用Retr ...
- 使用Fileupload完成文件的上传下载
目录 使用Fileupload完成文件的上传下载 为什么需要进行文件上传下载? 引入jar包 文件上传 注意事项 编写一个简单的文件上传jsp页面 编写Servlet Student类用于封装数据,后 ...
- 在Window的IIS中创建FTP的Site并用C#进行文件的上传下载
文件传输协议 (FTP) 是一个标准协议,可用来通过 Internet 将文件从一台计算机移到另一台计算机. 这些文件存储在运行 FTP 服务器软件的服务器计算机上. 然后,远程计算机可以使用 FTP ...
- 创建FTP的Site并用C#进行文件的上传下载
创建FTP的Site并用C#进行文件的上传下载 文件传输协议 (FTP) 是一个标准协议,可用来通过 Internet 将文件从一台计算机移到另一台计算机. 这些文件存储在运行 FTP 服务器软件的服 ...
- linux链接及文件互相上传下载
若排版紊乱可查看我的个人博客原文地址 基本操作 本篇博客主要介绍如何去链接远程的linux主机及如何实现本地与远程主机之间文件的上传下载操作,下面的linux系统是CentOS6.6 链接远程linu ...
- Spring实现文件的上传下载
背景:之前一直做的是数据库的增删改查工作,对于文件的上传下载比较排斥,今天研究了下具体的实现,发现其实是很简单.此处不仅要实现单文件的上传,还要实现多文件的上传. 单文件的下载知道了,多文件的下载呢? ...
- SocketIo+SpringMvc实现文件的上传下载
SocketIo+SpringMvc实现文件的上传下载 socketIo不仅可以用来做聊天工具,也可以实现局域网(当然你如果有外网也可用外网)内实现文件的上传和下载,下面是代码的效果演示: GIT地址 ...
随机推荐
- 第三人称角色移动及自由移动视野(RigidBody实现)
重点:向量的运算.在获得水平及垂直方向的速度之后,将方向进行重设,让方向与视野同步(即:相机的方向与人物方向相同) 下面以一个实例来说明如何操作: 1.如图创建一个地形(Terrain),两个正方体( ...
- 如何做到机器学习竞赛Kaggle排名前2%
原创文章,同步首发自作者个人博客 .转载请务必在文章开头显眼处注明出处 摘要 本文详述了如何通过数据预览,探索式数据分析,缺失数据填补,删除关联特征以及派生新特征等方法,在Kaggle的Titanic ...
- oracle实现like多关键字查询
oracle实现like多关键字查询: select * from contract_info tt where 1=1 and REGEXP_LIKE(tt.contract_name,'关键字1| ...
- sql中 datediff的使用
简介:我们在sql中经常要判断年或者月或者日是否相等,我们可以用datediff函数,使用很方便 datediff:判断年或月或日或周.星期.小时.分钟等的差别数使用格式: DATEDIFF(date ...
- [转载]前端构建工具gulpjs的使用介绍及技巧
转载地址:http://www.cnblogs.com/2050/p/4198792.html gulpjs是一个前端构建工具,与gruntjs相比,gulpjs无需写一大堆繁杂的配置参数,API也非 ...
- script defer和async一探
今天几经折腾,终于回家了,最近公司上的事忙了好一阵子,终于可以闲下来,重新在整理一下,又重新了解了一下defer和async在页面加载过程差异. 定义和用法 async 属性规定一旦脚本可用,则会异步 ...
- Extjs6(二)——用extjs6.0写一个系统登录及注销
本文基于ext-6.0.0 一.写login页 1.在view文件夹中创建login文件夹,在login中创建文件login.js和loginController.js(login.js放在class ...
- 保证Android后台不被杀死的几种方法
由于各种原因,在开发Android应用时会提出保证自己有一个后台一直运行的需求,如何保证后台始终运行,不被系统因为内存低杀死,不被任务管理器杀死,不被软件管家等软件杀死等等还是一个比较困难的问题.网上 ...
- 【原创】bootstrap框架的学习 第八课 -[bootstrap表单]
Bootstrap 提供了下列类型的表单布局: 垂直表单(默认) 内联表单 水平表单 吹着表单或基本表单 向父 <form> 元素添加 role="form". 把标签 ...
- 腾讯实习面经(offer)
腾讯的实习招聘也算是告一段落了.从内推到正式实习生招聘,总结一下.看了这么多面经,也把自己的经历写一下,有需要的朋友可以参考一下.毕竟互帮互助嘛. 内推 腾讯内推的经历比较惨淡,面了三个部门,都跪在一 ...