引
在网上找了几天的资料,发现他们的博客都是从工作中直接复制过来的吧,并不怎么友好,要么乱七八糟代码太多,没有写到精髓,要么就是方法太老,已经不适合.net mvc 和目前主流的前后端分离框架,单页面应用程序mvvm的使用了。
俗话说的好,自己动手,丰衣足食; 因此特意写一个简单的基于webapi 的上传后台。
此文章不讨论阿里云OSS等上传模式,确实简单好用,但是,谁让换了家小公司,服务器只有一个,既来之则安之,都有用就是了。
好,废话不多说,直接讲代码
前端
<form action="@(apiKey)/actionapi/ImgUpload/UpLoadImages" method="post" enctype="multipart/form-data">
<input type="file"/>
<input type="submit" value="提交" />
</form>
后端webApi
public class ImgUploadController : ApiController
{
#region webapi图片上传_接口版本
public JsonResult<AppReturnModel> UpLoadImages()
{
AppReturnModel result = new AppReturnModel();//返回模型,用来后面转成json,更标准更规范的来写
result.StatusCode = -1;//-1表示失败,请求失败
string now = DateTime.Now.ToString("yyyy-MM-dd");//获取当前时间年月日来分开存图片,也可以只获取到月,每个月的图片放一个文件夹,看心情
string upLoad = "UpLoad";//保存在项目中的文件夹名称
//文件流
HttpFileCollection files = HttpContext.Current.Request.Files;//核心获取文件
MessageHelper.WriteLog("【手机】开始调用UpdateImages");//可以不要,这是来写日志的,没用的可以直接删除就行
if (files != null && files.Count > 0)//判断是否获取到数据
{
for (int i = 0; i < files.Count; i++)//假如有多张图,来循环一下
{
string file_name = "";
#region 以下方法是用来处理,有个别傻子在前台上传的时候没有把图片后缀传进来,特别是IOS或者安卓也能用的时候,IOS经常就传进来没后缀名,手机上能看,电脑看不了,所以,如果没用,也可以把这段删掉
if (!files[i].FileName.Contains("png") && !files[i].FileName.Contains("jpg") && !files[i].FileName.Contains("gif") && !files[i].FileName.Contains("jpeg"))
{
file_name = files[i].FileName + ".png";
}
else
{
file_name = files[i].FileName;
}
#endregion
//获取文件的保存路径
//文件夹是否存在
if (!Directory.Exists(HttpContext.Current.Server.MapPath("~/UpLoad")))
{
Directory.CreateDirectory(HttpContext.Current.Server.MapPath("~/UpLoad"));
}
string uploadPath = HttpContext.Current.Server.MapPath("\\" + upLoad + "\\" + now);
//判断上传的文件是否为空
//如果没有UpLoad这个文件夹
if (!Directory.Exists(uploadPath))
{
Directory.CreateDirectory(uploadPath);
}
// 保存到 ~/UpLoad 文件夹中,给图片一个新的命名,规范,规范
string filename = Guid.NewGuid().ToString("N") + Path.GetExtension(file_name);
string virtualPath =
string.Format("/" + upLoad + "/{0}/{1}", now, filename);
// 文件系统不能使用虚拟路径
string path = HttpContext.Current.Server.MapPath(virtualPath);
files[i].SaveAs(path);
//返回虚拟路径
result.StatusCode = 0;
result.StatusMsg = "Success";
result.Body = new { path = virtualPath };
}
}
else
{
result.StatusCode = -1;
result.StatusMsg = "未上传图片";
}
return Json(result);
}
#endregion
}
进阶,使用现成的jquery插件,来完成上传
引用的插件我就不说了,下载http://www.uploadify.com/ 下载flash版本
页面引用:uploadify.css
jquery.uploadify.js
前端
随便定义一个空间,设置上id就行
<input type="button" id="uploadImg"/>
JQ
$(function () {
//上传
$('#uploadImg').uploadify({
uploader: '@apiKey' +"/actionapi/ImgUpload/UpLoadImages",
//uploader: 'http://up.courseware.rx/UploadHandler.ashx?xz=1',
//uploader: 'http://up.courseware.rx/UploadHandler.ashx?filePath=1',
swf: '../../Areas/Admin/Content/vendor/upload/uploadify.swf', // 上传使用的 Flash
width: 100, // 按钮的宽度
height: 115, // 按钮的高度
buttonText: "", // 按钮上的文字
buttonCursor: 'hand', // 按钮的鼠标图标
fileObjName: 'Filedata', // 上传参数名称
fileSizeLimit: '100MB', //1M:1*1024*1024
// 两个配套使用
fileTypeExts: "*.jpg;*.jpeg;*.png;*.gif", // 扩展名
fileTypeDesc: "请选择图片格式文件", // 文件说明
auto: true, // 选择之后,自动开始上传
multi: true, // 是否支持同时上传多个文件
queueSizeLimit: 20, // 允许多文件上传的时候,同时上传文件的个数
removeCompleted: true, //文件上传完成后,是否自动移除队列中的文件
uploadLimit: 20, //最大上传文件数量,如果达到或超出此限制将会触发onUploadError事件。
onSelect: function (file) { //选择文件后向队列中添加每个上传任务时都会触发。
//$(".loadingDiv").show();
},
onUploadSuccess: function (file, data, response) {
//上传成功后,拿到返回的json,绑定图片到前台页面
if (data.StatusCode==0) {
}
//alert(data);
},
onUploadError: function (file, errorCode, errorMsg, errorString) {
alert('上传失败原因:' + errorString);
//$(".loadingDiv").hide();
},
onQueueComplete: function (queueData) {
}
});