.NET WebAPI 实现图片上传(包括附带参数上传图片)

博主的项目,客户端是APP,考虑到以后也可能会应用到微信端、网站等,图片上传方法就需要兼容多端,并且以目前的设计,不允许非登录用户上传图片,就得在上传时解决附带参数上传图片的问题。

先来看看后台方法(逻辑都写在了一起,有点乱,分布式文件系统还没做好,暂时存在了本地...):

         /// <summary>
/// 图片上传 [FromBody]string token
/// </summary>
/// <returns></returns>
[HttpPost]
[Route("api/Upload/ImgUpload")]
public Task<Hashtable> ImgUpload()
{
// 检查是否是 multipart/form-data
if (!Request.Content.IsMimeMultipartContent("form-data"))
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); // 文件保存目录路径
const string saveTempPath = "~/UploadFiles/";
var dirTempPath = HttpContext.Current.Server.MapPath(saveTempPath); // 设置上传目录
var provider = new MultipartFormDataStreamProvider(dirTempPath); var task = Request.Content.ReadAsMultipartAsync(provider).
ContinueWith<Hashtable>(o =>
{
var hash = new Hashtable();
var file = provider.FileData[];
// 最大文件大小
const int maxSize = ;
// 定义允许上传的文件扩展名
const string fileTypes = "gif,jpg,jpeg,png,bmp"; // token验证
var token = string.Empty;
try
{
token = provider.FormData["token"].ToString();
}
catch (Exception exception)
{
throw new Exception("未附带token,非法访问!", exception);
} if (!string.IsNullOrEmpty(token))
{
if (!CacheManager.TokenIsExist(token))
{
throw new UserLoginException("Token已失效,请重新登陆!");
}
if (accountInfoService.Exist_User_IsForzen(AccountHelper.GetUUID(token)))
{
CacheManager.RemoveToken(token);
tempCacheService.Delete_OneTempCaches(new Guid(token));
throw new UserLoginException("此用户已被冻结,请联系管理员(客服)!");
}
}
else
{
throw new Exception("token为空,非法访问!");
} string orfilename = file.Headers.ContentDisposition.FileName.TrimStart('"').TrimEnd('"');
var fileinfo = new FileInfo(file.LocalFileName);
if (fileinfo.Length <= )
{
hash["Code"] = -;
hash["Message"] = "请选择上传文件。";
}
else if (fileinfo.Length > maxSize)
{
hash["Code"] = -;
hash["Message"] = "上传文件大小超过限制。";
}
else
{
var fileExt = orfilename.Substring(orfilename.LastIndexOf('.')); if (String.IsNullOrEmpty(fileExt) ||
Array.IndexOf(fileTypes.Split(','), fileExt.Substring().ToLower()) == -)
{
hash["Code"] = -;
hash["Message"] = "不支持上传文件类型。";
}
else
{
try
{
AttachmentFileResultDTO attachmentFileResult;
attachmentFileService.UploadAttachmentFile(fileinfo, dirTempPath, fileExt,
Path.GetFileNameWithoutExtension(file.LocalFileName), out attachmentFileResult); hash["Code"] = ;
hash["Message"] = "上传成功";
hash["FileId"] = attachmentFileResult.ID;
hash["FileName"] = attachmentFileResult.FileName + attachmentFileResult.FileType;
hash["NetImageUrl"] = attachmentFileResult.FileUrl;
}
catch (Exception exception)
{
throw new Exception("上传失败!", exception);
}
}
}
return hash;
});
return task;
}

注:

1.第31行至57行是对附带参数token进行验证,因为博主的需求是只开放登录用户上传图片

2.第34行一定要tostring(),因为我们的参数也是以二进制数据格式上传的

前台目前是以jquery做的测试,使用了ajaxfileupload.js来上传文件。不过博主下载的ajaxfileupload.js并不支持附带参数上传,不知道是不是没找到好资源,不管了,自己打开文件瞅瞅...源码也不长一两百行,那就自己动手改改呗。(如果你已下载到支持附带参数上传的js,请自动忽略这一部分)

找到createUploadForm这个函数,OK,顾名思义它是用来创建FORM的,看看博主下载版本的源码:

   createUploadForm: function (id, fileElementId) {
//create form
var formId = 'jUploadForm' + id;
var fileId = 'jUploadFile' + id;
var form = jQuery('<form action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
var oldElement = jQuery('#' + fileElementId);
var newElement = jQuery(oldElement).clone();
jQuery(oldElement).attr('id', fileId);
jQuery(oldElement).before(newElement);
jQuery(oldElement).appendTo(form);
//set attributes
jQuery(form).css('position', 'absolute');
jQuery(form).css('top', '-1200px');
jQuery(form).css('left', '-1200px');
jQuery(form).appendTo('body');
return form;
},

我们添加参数data,并在第5行后面插入下列代码:

       if (data) {
for (var i in data) {
if (data.hasOwnProperty(i)) {
jQuery('<input type="hidden" name="' + i + '" value="' + data[i] + '" />').appendTo(form);
}
}
}

再找到调用这个函数的地方,ajaxFileUpload函数中有这样一行:

var form = jQuery.createUploadForm(id, s.fileElementId);

OK,修改成我们重构后的调用:

var form = jQuery.createUploadForm(id, s.fileElementId,(typeof(s.data) == 'undefined' ? false : s.data));

到这一步,我们就可以jquery调用ajaxfileupload执行文件上传并且附带参数了。

    $.ajaxFileUpload({
url: "/api/Upload/ImgUpload",
secureuri: false,
fileUpload: file,
dataType: 'json',
data: { "token": token },
success: function (data, status) {
var str = $(data).text();
var result = JSON.parse(str);
successFn(result, key);
}, error: function (data, status, e) {
failFn();
}
});

具体的ajaxfileupload.js下载路径:http://download.csdn.net/detail/cb511612371/9173749

附上做测试随意写的文件上传通用方法一份,可能有点丑...求轻喷(会有部分逻辑是博主测试的功能需求决定的,如使用,请自己过滤处理)

 //图片上传
window.proHub = {};
common = {};
/**================================================================
文件上传
=================================================================*/
common.uploadTemplate = '<li class="fl pr">' +
'<div class="plus abs-mm fullLayer">' +
'<span class="abs-mm"></span>' +
'<span class="abs-mm"></span>' +
'</div>' +
'<img class="abs-mm hidden"/>' +
'<input class="file-input" type="file" name="file{0}" accept="image/*" onchange="fileUploadChange(this);"/>' +
'<div class="file-img-del hidden"></div>' +
'</li>'; // 文件上传
common.fileIndex = ;
// 添加文件上传框
common.appendFileUpload = function ($container, imgData, key) {
var h = "hidden"; var $list = $container.find("li");
var t = $container.attr("limit");//
var len = t === undefined ? : t;//
var canAdd = len != $list.length;
var $prev = $container.find("li:last");
var str = common.uploadTemplate; // 执行上传
if ($.trim($container.html()).length > ) {
common.uploadImage(uploadResult, $container);
} imgData && ($prev.find("img").removeClass(h).get().src = imgData);
$prev.find(".plus").addClass(h);
$prev.find("[type=file]").addClass(h);
$prev.find(".file-img-del").removeClass(h);
canAdd && $container.append(str.format(common.fileIndex)); common.fileIndex++;
} // 上传文件控件change
function fileUploadChange(fileControl) {
var imgClass = ".img-preview-list";
var h = "hidden";
viewFile(fileControl); function viewFile(fileControl) {
var file = fileControl.files[]; var reader = new FileReader();
reader.onload = function (evt) {
var data = evt.target.result;
var $par = $(fileControl).parents(imgClass);
common.appendFileUpload($par, data);
}
reader.readAsDataURL(file);
}
} // 上传成功和删除图片回调方法
var imgUrl = { "head_img": null, "card_zheng": null, "card_fan": null, "certificate": null, "license": null };
uploadResult = function (fileId, key) {
imgUrl[key] = fileId;
// 点击查看大图
$(".openPhoto img").click(function () {
$("#big_photo").attr("src", $(this).attr("src"));
$.fancybox.open($("#panel"));
});
} common.uploadImgInit = function () {
var imgClass = ".img-preview-list";
var $box = $(imgClass); $box.on("click", ".file-img-del", function () {
var $par = $(this).parents(imgClass);
var len = $par.find("li").length;
if (len == ) {
var str = common.uploadTemplate;
$par.append(str);
}
uploadResult(null, $par.attr("key"));
$(this).parent().remove();
}); $box.each(function (index, item) { common.appendFileUpload($(item));
});
}; // 上传图片到服务器
common.uploadImage = function (submit, $box) {
var files = $box.find("[type=file]");
var count = ;
var imgKey = $box.attr("key");
var map = {}; $(files).each(function (index, item) {
if (item.files.length) {
imgKey = $(this).parent().parent().attr("key");
count++;
proHub.uploadImage(item, successFn, failFn, imgKey);
}
});
if (!count) {
submit();
}
var curIndex = ;
function successFn(result, key) {
if (result.Code == ) {
map[key] = result["FileId"];
curIndex++; if (curIndex == count) {
submit(map[key], key);
}
} else {
Config.Method.JudgeCode(result, );
}
} function failFn() {
alert("图片上传失败,请重试!");
$(".file-img-del").click();
}
} proHub.uploadImage = function (file, successFn, failFn, key) {
$.ajaxFileUpload({
url: "/api/Upload/ImgUpload",
secureuri: false,
fileUpload: file,
dataType: 'json',
data: { "token": token },
success: function (data, status) {
var str = $(data).text();
var result = JSON.parse(str);
successFn(result, key);
}, error: function (data, status, e) {
failFn();
}
});
};

如果有写的不好或不对的地方,欢迎指出,必定及时纠正,虚心请教。

原创文章,代码都是从自己项目里贴出来的。转载请注明出处哦,亲~~~

上一篇:九度oj 题目1034:寻找大富翁


下一篇:利用linux漏洞进行提权