分类:
工具
最近一段时间都在使用PlUpload做文件上传的功能,研究过后感觉使用起来体验还是比较好的,不过网上的资料很多都记录的很简便,故此记录一下,方便自己使用,也给需要的朋友提供多一个文件上传的选择。由于这篇文章比较长,我遇到坑的地方就不给大家一一举例了,要是小伙伴们想经历的话,可以先不看文章,自己去尝试一下。附上一篇中文介绍文档:https://www.cnblogs.com/2050/p/3913184.html;话不多说,直接上代码:
这部分是我页面上的代码,由于为了方便使用,我的上传写成了一个用户控件,页面上只需要引用即可,UploadControl是引用控件的部分:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="FileUpload.aspx.cs" Inherits="EPC.FileManager.Page.FileUpload" %> <%@ Register Src="~/UserControls/UploadControl.ascx" TagPrefix="uc1" TagName="UploadControl" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> </head> <body> <form id="form1" runat="server"> <div> <uc1:UploadControl runat="server" ID="UploadControl" /> </div> </form> </body> </html>
这一块是我的上传控件部分:
首先是需要添加的引用:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="UploadControl.ascx.cs" Inherits="EPC.FileManager.UserControls.UploadControl" %> <link href="../Themes/CSS/reset.css" rel="stylesheet" /> <link href="../Themes/CSS/index.css" rel="stylesheet" /> <script src="../Scripts/jQuery/jquery-1.11.1.min.js"></script> <script src="../Scripts/plupload/plupload.full.min.js"></script> <script src="../Scripts/jQuery/index.js"></script> <!--用于保存所有上传成功的文件的URL--> <input type="hidden" id="fileUploadUrl" runat="server" />
然后是我的上传文件的界面布局,你们也可以自己更改为自己喜欢的风格,放上来只是为了便于讲解:
<section class="center-box"> <div class="container"> <div class="center clearfix"> <div class="line-lebel"> 文件上传: </div> <div class="line-box"> <!--上传下载开始--> <div class="J-upload-box clearfix"> <div class="J-upload-area"> <div class="J-need-upload-file clearfix"> <div class="J-handle-btns"> <b class="J-continue-add" id="choseFileBtn"><i id="JcontinueAdd">选择文件</i> </b> <b class="J-to-upload" id="JToUpload">开始上传</b> </div> </div> <div class="J-show-the-name clearfix" style="display: none;"> <!--选择文件和图片的时候 显示文件名--> <div class=" " id="JShowFileBox"> <div class="J-folding"><span>收起<i></i></span></div> <ul class="J-file-img J-calc-len clearfix" id="JShowFileImg"> <%--<li title="J-folding.png"> <em>J-folding.png</em><span></span> </li>--%> </ul> </div> <!--只选择图片时--> <div class="J-imgs-box" id="JShowImgsBox"> <ul class="J-imgs J-calc-len clearfix" id="JShowImgs"> <%--<li title="2.jpg"> <em> <img src="img/1.jpg"></em><span></span> </li> --%> </ul> </div> </div> </div> <!--进度条--> <div class="ProgressBar" style="display: none"> <div id="progress" style="width: 0%"></div> </div> <!--用户点击“开始上传”后的展示区域(已上传文件展示开始)--> <div class="J-show-all " id="JShowAll" style="display: none;"> <div class="J-show-all-center"> <div class="J-title" id="JTitle">已完成上传</div> <!--选择文件和图片的时候 显示文件名--> <div class="J-file-img-box "> <div class="J-folding"><span>收起<i></i></span></div> <ul class="J-file-img J-calc-len clearfix" id="JUploadFileImg"> </ul> </div> <!--只选择图片时--> <div class="J-imgs-box"> <ul class="J-imgs J-calc-len clearfix" id="JUploadImgs"> </ul> </div> </div> </div> <!--已上传文件展示结束--> </div> </div> <!--上传下载结束--> </div> </div> </section>
界面效果是这样的,比较简陋,haha...:

这个部分就是plupload控件的核心了,这个对象有许多的方法,大家可以根据自己的需求去研究和使用:
<script>
// 实例化一个plupload上传对象,并根据需要进行相应的设置:
var uploader = new plupload.Uploader({
// 触发文件选择对话框的按钮,为哪个元素id
browse_button: 'choseFileBtn',
// 服务器端的上传页面地址,路径根据自己的实际情况配置
url: '../Handler/UploadHandler.ashx',
// swf文件,当需要使用swf方式进行上传时需要配置该参数
flash_swf_url: '../Scripts/plupload/moxie.swf',
// silverlight文件,当需要使用silverlight方式进行上传时需要配置该参数
silverlight_xap_url: '../Scripts/plupload/moxie.xap',
// 文件大小及类型相关设置
filters: {
// 最大只能上传200mb的文件
max_file_size: '200mb',
// 不允许队列中存在重复文件
prevent_duplicates: true,
// 允许上传的文件类型
mime_types: [{ title: 'FileTypes', extensions: 'doc,xls,xlsx,jpg,gif,png,jpeg,zip,rar' }]
}
});
// 在实例对象上调用init()方法进行初始化
uploader.init();
// 文件上传前
uploader.bind('FilesAdded', function (uploader, files) {
// 判断是否包含文件
var isFile = false;
// 判断是否包含图片
var isPic = false;
// 定义一个数组存放文件类型,这里我暂时还没想到怎么获取文件类型,所以用一个固定的代替,好像这个控件里面有些jQuery的函数使用不了,再研究下
var picTypeArr = ["image/png", "image/jpeg", "image/jpg"];
// 根据文件类型选择展示框
for (var i = 0; i < files.length; i++) {
isPic = false;
// 获取文件类型
var fileType = files[i].type;
// 判断文件类型是图片还是文件(暂时指定数组中的三种类型为图片类型,其它默认为文件类型)
for (var j = 0; j < picTypeArr.length; j++) {
if (picTypeArr[j] == fileType) {
isPic = true;
}
}
// 根据文件类型选择文件展示框
if (isPic == true) {
// 拼接文件展示框HTML
var html = '<li title="' + files[i].name + '" id="' + files[i].id + '"><em></em><span class="del_WaitUpload" FileId="' + files[i].id + '"></span></li>';
// 展示待上传图片
$("#JShowImgs").append(html);
!function (i) {
// 图片预览(图片预览目前仅支持以上三种图片类型,大家可以再研究下其它图片类型怎么预览)
previewImage(files[i], function (imgsrc) {
$('#' + files[i].id).find("em").append('<img class="imgZoom" src="' + imgsrc + '" />');
})
}(i);
} else {
var html = '<li title="' + files[i].name + '" id="' + files[i].id + '"><em>' + files[i].name + '</em><span class="del_WaitUpload" FileId="' + files[i].id + '"></span></li>';
// 展示待上传文件
$("#JShowFileImg").append(html);
}
}
// 获取点击“开始上传”后待上传文件展示区域文件的个数
var waitUploadFileLiLen = $("#JShowFileImg").find('li').length;
var waitUploadPicLiLen = $("#JShowImgs").find("li").length;
// 待上传的文件如果不为空,展示待上传文件展示框,
if (waitUploadFileLiLen > 0 || waitUploadPicLiLen > 0) {
$(".J-show-the-name").show();
}
// 重新计算待上传的文件展示宽度(针对图片展示框),这个方法在index.js文件中
Funs.setImgWidth($("#JShowImgs li"));
});
// 文件上传过程中不断触发,用来显示上传进度
uploader.bind('UploadProgress', function (uploader, file) {
// 禁用选择文件和开始上传按钮
$("#choseFileBtn").attr("disabled", true);
$("#JToUpload").attr("disabled", true);
// 展示进度条(这个进度条是随意写的,大家可以自行替换为自己想要的效果)
uploadProcess(file.percent);
});
// 当队列中的某一个文件正要开始上传前触发
uploader.bind('BeforeUpload', function (uploader, file) {
// 禁用选择文件和开始上传按钮
$("#choseFileBtn").attr("disabled", true);
$("#JToUpload").attr("disabled", true);
// 清理进度条
clearProcess();
});
// 队列中的某一个文件上传完成后触发
uploader.bind('FileUploaded', function (uploader, file, responseObject) {
// 接收上传响应信息
var resp = JSON.parse(responseObject.response)
// 判断上传是否成功
if (resp.StatusCode == 1) {
// 判断是否包含图片
var isPic = false;
// 定义两个数组存放文件类型
var picTypeArr = [".png", ".jpeg", ".jpg"];
// 判断文件类型是图片还是文件
for (var j = 0; j < picTypeArr.length; j++) {
//isPic = false;
if (picTypeArr[j] == resp.FileType) {
isPic = true;
}
}
// 根据文件类型选择展示框
if (isPic == true) {
// 上传成功,展示已上传图片
var html = '<li title="' + resp.FileName + '"><em><img src="' + resp.FileUrl + '"></em><span class="del_Uploaded" fileurl="' + resp.FileUrl + '"></span></li>';
$("#JUploadImgs").append(html);
}
else {
// 上传成功,展示已上传文件
var html = '<li title="' + resp.FileName + '" ><em><a href="' + resp.FileUrl + '">' + resp.FileName + '</a></em><span class="del_Uploaded" fileurl="' + resp.FileUrl + '"></span></li>';
// 展示已完成上传文件
$("#JUploadFileImg").append(html);
}
// 判断已上传文件展示框是否为空,不为空则展示
var uploadFileLiLen = $("#JUploadFileImg").find("li").length;
var uploadPicLiLen = $("#JUploadImgs").find("li").length;
if (uploadFileLiLen > 0 || uploadPicLiLen > 0) {
// 展示已上传文件展示框
$("#JShowAll").show();
// 清除进度条并隐藏
clearProcess();
// 删除上传队列中文件(注意:上传成功后必须移除uploader对象中的文件,否则会对之后的上传功能造成影响)
uploader.removeFile(file);
// 移除对应的待上传文件展示框li
$("#" + file.id + "").remove();
// 判断待上传文件展示框是否为空,为空则隐藏
var waitUploadFileLiLen = $("#JShowFileImg").find('li').length;
var waitUploadPicLiLen = $("#JShowImgs").find("li").length;
if (waitUploadFileLiLen == 0 && waitUploadPicLiLen == 0) {
// 隐藏待上传文件展示框
$(".J-show-the-name").hide();
}
// 保存已上传文件的URL
var fileUrl = $("#UploadControl_fileUploadUrl").val();
if (fileUrl != null && fileUrl != "") {
$("#UploadControl_fileUploadUrl").val($("#UploadControl_fileUploadUrl").val() + "," + resp.FileUrl)
}
else {
$("#UploadControl_fileUploadUrl").val(resp.FileUrl)
}
}
}
else {
// 弹出上传失败的提示信息
alert(resp.Message);
clearProcess();
return;
}
});
// 当上传队列中所有文件都上传完成后触发
uploader.bind('UploadComplete', function (uploader, files) {
// 取消禁用选择文件和开始上传按钮
$("#upload-btn-add").attr("disabled", false);
$(".upload-btn").attr("disabled", false);
// 删除已上传文件
$(".del_Uploaded").click(function () {
// 移除当前被删除文件的URL
var fileDelUrl = $(this).attr("fileurl");
var uploadArray = $("#UploadControl_fileUploadUrl").val().split(',');
for (var i = 0; i < uploadArray.length; i++) {
if (uploadArray[i] == fileDelUrl) {
uploadArray.splice(i, 1);
}
}
// 将保存上传文件URL的input重赋值
$("#UploadControl_fileUploadUrl").val(uploadArray);
// 移除删除文件的li
$(this).parent().remove();
// 判断ul是否为空
var uploadFileLiLen = $("#JUploadFileImg").find("li").length;
var uploadPicLiLen = $("#JUploadImgs").find("li").length;
if (uploadFileLiLen == 0 && uploadPicLiLen == 0) {
$("#JShowAll").hide();
}
});
});
// 当上传出错时触发
uploader.bind('Error', function (uploader, errObject) {
//每个事件监听函数都会传入一些很有用的参数,
//我们可以利用这些参数提供的信息来做比如更新UI,提示上传进度等操作
});
//最后给"开始上传"按钮注册事件
document.getElementById('JToUpload').onclick = function () {
//调用实例对象的start()方法开始上传文件,当然你也可以在其他地方调用该方法
uploader.start();
}
// 删除待上传队列中的文件
$("#JShowFileImg,#JShowImgs").on('click', '.del_WaitUpload', function (e) {
// 获取想要删除的上传队列文件的ID
var FileId = $(this).attr("FileId");
// 根据文件ID获取想要删除的文件
var file = uploader.getFile(FileId);
// 从uploader对象中移除目标文件
uploader.removeFile(file);
// 同时移除展示文件的li
$(this).parent().remove();
// 获取待上传文件的数量
var waitUploadFileLiLen = $("#JShowFileImg").find('li').length;
var waitUploadPicLiLen = $("#JShowImgs").find("li").length;
if (waitUploadFileLiLen == 0 && waitUploadPicLiLen == 0) {
$(".J-show-the-name").hide();
}
// 重新计算未上传的文件展示宽度
Funs.setImgWidth($("#JShowImgs li"));
});
// 上传进度条显示
function uploadProcess(t) {
// 展示进度条
$(".ProgressBar").show();
// 进度条百分比框
var jindutiao = document.getElementById("progress");
jindutiao.style.width = t + "%";
jindutiao.innerHTML = jindutiao.style.width;
}
// 清理进度条框文本并隐藏进度条
function clearProcess() {
var jindutiao = document.getElementById("progress");
jindutiao.style.width = "0%";
jindutiao.innerHTML = "0%";
// 隐藏进度条
$(".ProgressBar").hide();
}
// 图片预览
function previewImage(file, callback) {
if (!file || !/image\//.test(file.type)) return;
if (file.type == 'image/gif') {
var fr = new mOxie.FileReader();
fr.onload = function () {
callback(fr.result);
fr.destroy();
fr = null;
}
fr.readAsDataURL(file.getSource());
} else {
var img = new moxie.image.Image();
img.load(file.getSource());
img.onload = function () {
img.downsize(300, 300);// 压缩要预览的图片,宽300,高300
var imgsrc = img.type == 'image/jpeg' ? img.getAsDataURL('image/jpeg', 90) : img.getAsDataURL(); // 得到图片src,base64编码的数据
callback && callback(imgsrc); // callback传入的参数为预览图片的url
img.destroy();
img = null;
};
}
}
</script>
接下来是我后台的代码,如果只是想了解plupload控件的朋友就可以不用看下去了,这些算是我自己对自己的一个总结:
这是我handler的部分,主要是接收控件传进来的文件并传入文件上传方法及返回上传结果:
using EPC.Components.FileManage;
using EPC.FileManage.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Script.Serialization;
namespace EPC.FileManager.Handler
{
/// <summary>
/// UploadHandler 的摘要说明
/// </summary>
public class UploadHandler : IHttpHandler
{
/// <summary>
/// 文件上传
/// <author>Asa</author>
/// <createDate>2019-05-01</createDate>
/// </summary>
/// <param name="context">http上下文对象</param>
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
context.Response.Clear();
// 声明一个用于序列化的对象
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
// 判断待上传文件是否为空
if (context.Request.Files.Count > 0)
{
for (int i = 0; i < context.Request.Files.Count; i++)
{
// 接收待上传的文件对象
HttpPostedFile file = HttpContext.Current.Request.Files[i];
// 调用上传文件的方法
EPC_UploadResponse epc_UploadResponse = EPC_FileManage.UploadFile(file);
// 返回上传结果
HttpContext.Current.Response.Write(javaScriptSerializer.Serialize(epc_UploadResponse));
}
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
}这一块是我上传方法的部分:
using EPC.Common;
using EPC.FileManage.Entity;
using System;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Script.Serialization;
namespace EPC.Components.FileManage
{
/// <summary>
/// EPC文件管理类
/// <author>Asa</author>
/// <createDate>2019-05-15</createDate>
/// </summary>
public class EPC_FileManage
{
public static EPC_UploadResponse UploadFile(HttpPostedFile file)
{
#region 读取文件上传相关配置,定义文件上传所需变量--BEGIN
// 定义一个变量接收待上传文件名称
string fileName = string.Empty;
// 定义一个变量接收待上传文件类型
string fileType = string.Empty;
// 读取允许上传的文件类型配置
string allowedFileType = ConfigurationManager.AppSettings["allowedFileType"];
// 定义一个数组接收允许上传的文件类型
string[] allowedFileTypeArray = null;
// 读取允许上传的文件大小(KB)
string allowedFileSizeStr = ConfigurationManager.AppSettings["allowedFileSize"];
// 定义一个变量接收转换为int类型的allowedFileSize
int allowedFileSizeInt = 0;
// 读取API请求地址前缀
string apiUrlPrefix = ConfigurationManager.AppSettings["apiUrlPrefix"];
// 定义一个变量拼接完整的接口请求地址
string apiFullUrl = string.Empty;
// 创建一个上传结果响应类对象
EPC_UploadResponse epcUploadResponse = new EPC_UploadResponse();
// 定义一个用于反序列化的对象
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
#endregion 读取文件上传相关配置,定义文件上传所需变量--END
#region 判断文件上传相关配置是否合法及上传文件是否为空--BEGIN
// 判断允许上传的文件类型配置是否为空
if (string.IsNullOrEmpty(allowedFileType))
{
epcUploadResponse.StatusCode = 001;
epcUploadResponse.Message = "上传失败:缺少允许上传的文件类型配置";
return epcUploadResponse;
}
// 判断允许上传的文件大小配置是否为空
if (string.IsNullOrEmpty(allowedFileSizeStr))
{
epcUploadResponse.StatusCode = 001;
epcUploadResponse.Message = "上传失败:缺少允许上传的文件大小配置";
return epcUploadResponse;
}
// 判断API请求地址前缀配置是否为空
if (string.IsNullOrEmpty(apiUrlPrefix))
{
epcUploadResponse.StatusCode = 001;
epcUploadResponse.Message = "上传失败:缺少请求API的地址前缀配置";
return epcUploadResponse;
}
// 判断待上传文件是否为空。
if (file == null)
{
epcUploadResponse.StatusCode = 001;
epcUploadResponse.Message = "上传失败:缺少文件";
return epcUploadResponse;
}
#endregion 判断文件上传相关配置是否合法及上传文件是否为空--END
#region 判断文件格式和大小是否符合规则--BEGIN
// 接收允许上传的文件类型
try
{
allowedFileTypeArray = allowedFileType.Split(',');
}
catch
{
epcUploadResponse.StatusCode = 001;
epcUploadResponse.Message = "上传失败:允许上传文件类型配置不合法";
return epcUploadResponse;
}
// 接收允许上传的文件大小
try
{
allowedFileSizeInt = Convert.ToInt32(allowedFileSizeStr);
}
catch
{
epcUploadResponse.StatusCode = 001;
epcUploadResponse.Message = "上传失败:允许上传文件大小配置不合法";
return epcUploadResponse;
}
// 获取待上传文件的文件名
fileName = file.FileName;
// 获取待上传文件的类型
fileType = Path.GetExtension(fileName);
// 判断文件类型是否合法
if (!allowedFileTypeArray.Contains(fileType))
{
epcUploadResponse.StatusCode = 001;
epcUploadResponse.Message = "上传失败:‘" + fileType + "’文件格式不合法" + allowedFileTypeArray + "";
return epcUploadResponse;
}
// 判断允许上传的文件大小是否超过默认最大值
if ((allowedFileSizeInt / 1024) <= 200)
{
if ((file.ContentLength / 1024) > allowedFileSizeInt)
{
epcUploadResponse.StatusCode = 001;
epcUploadResponse.Message = "上传失败:‘" + (file.ContentLength / 1024) + "kb’文件大小不合法";
return epcUploadResponse;
}
}
else
{
if ((file.ContentLength / 1024 / 1024) > 200)
{
epcUploadResponse.StatusCode = 001;
epcUploadResponse.Message = "上传失败:‘" + (file.ContentLength / 1024 / 1024) + "kb’文件大小不合法";
return epcUploadResponse;
}
}
#endregion 判断文件格式和大小是否符合规则--END
#region API接口方式上传
try
{
// API请求地址
apiFullUrl = apiUrlPrefix + "/" + "API/UploadFile/Save";
// 待上传文件流
Stream waitUploadStream = file.InputStream;
// 待压缩字节
byte[] waitCompressByte = Utiles.StreamToBytes(waitUploadStream);
// 已压缩字节
byte[] compressedByte = Utiles.CompressBytes(waitCompressByte);
// 待上传文件流
waitUploadStream = Utiles.BytesToStream(compressedByte);
// 接收文件上传返回结果
string uploadResponse = Utiles.HttpPostUpload(apiFullUrl, file.FileName, waitUploadStream);
// 反序列化响应结果并赋值给文件上传响应实体
epcUploadResponse = javaScriptSerializer.Deserialize<EPC_UploadResponse>(uploadResponse);
}
catch (Exception ex)
{
epcUploadResponse.StatusCode = 002;
epcUploadResponse.Message = "文件上传失败:无法连接到服务器";
return epcUploadResponse;
}
#endregion
// 返回上传结果响应类
return epcUploadResponse;
}
}
}
这部分是我的公共方法代码:
using System;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Text;
namespace EPC.Common
{
/// <summary>
/// 文件管理系统工具类
/// <author>Asa</author>
/// <createDate>20190507</createDate>
/// </summary>
public class Utiles
{
/// <summary>
/// 文件流转字节
/// </summary>
/// <author>Asa</author>
/// <createDate>20190507</createDate>
/// <param name="stream">文件流</param>
/// <returns></returns>
public static byte[] StreamToBytes(Stream stream)
{
byte[] array = new byte[stream.Length];
stream.Seek(0L, SeekOrigin.Begin);
stream.Read(array, 0, array.Length);
stream.Close();
return array;
}
/// <summary>
/// 将字节转为文件流
/// </summary>
/// <author>Asa</author>
/// <createDate>20190507</createDate>
/// <param name="stream">字节</param>
/// <returns></returns>
public static Stream BytesToStream(byte[] bytes)
{
return new MemoryStream(bytes);
}
/// <summary>
/// 模拟POST提交上传请求
/// <author>Asa</author>
/// <createDate>20190507</createDate>
/// </summary>
/// <param name="url">自定义请求url</param>
/// <param name="fileName">上传的文件名</param>
/// <param name="stream">流</param>
/// <param name="timeOut">超时时间[暂未使用]</param>
/// <returns>返回字符串类型</returns>
public static string HttpPostUpload(string url, string fileName, Stream stream, int timeOut = 0)
{
// 定义一个相应内容对象
string responseContent;
// 定义一个内存流对象(用于接收待上传文件)
MemoryStream memStream = new MemoryStream();
// 定义一个发送自定义post请求的对象
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
// 边界符
string boundary = "----WebKitFormBoundaryut99VQ34SOB8NU0X\r\n";
// 边界符
byte[] beginBoundary = Encoding.ASCII.GetBytes("--" + boundary);
// 最后的结束符
byte[] endBoundary = Encoding.ASCII.GetBytes("------WebKitFormBoundaryut99VQ34SOB8NU0X--\r\n");
// 设置属性
webRequest.Method = "POST";
webRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
webRequest.ContentType = "multipart/form-data; boundary=" + boundary;
// 开始时间参数(你可以把你需要的参数写在请求头里面传进接口)
string dateNow = DateTime.Now.ToString("yyyyMMdd");
webRequest.Headers.Add("dateNow", dateNow);
// 写入文件
const string filePartHeader =
"Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\";\r\n" + "datenow=\"{2}\"\r\n" +
"Content-Type: application/octet-stream\r\n\r\n";
string header = string.Format(filePartHeader, "file", fileName, dateNow);
byte[] headerbytes = Encoding.UTF8.GetBytes(header);
memStream.Write(beginBoundary, 0, beginBoundary.Length);
memStream.Write(headerbytes, 0, headerbytes.Length);
// 将文件流转换为字节
byte[] temp = StreamToBytes(stream);
// 将字节写入内存流
memStream.Write(temp, 0, temp.Length);
byte[] tt = Encoding.UTF8.GetBytes("\r\n");
memStream.Write(tt, 0, tt.Length);
// Key-Value数据
var stringKeyHeader = "--" + boundary +
"\r\nContent-Disposition: form-data; name=\"{0}\"" +
"\r\n\r\n{1}\r\n";
// 写入最后的结束边界符
memStream.Write(endBoundary, 0, endBoundary.Length);
Stream requestStream = webRequest.GetRequestStream();
StreamWriter myStreamWriter = new StreamWriter(requestStream, Encoding.GetEncoding("utf-8"));
memStream.Position = 0;
byte[] tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, 0, tempBuffer.Length);
memStream.Close();
requestStream.Write(tempBuffer, 0, tempBuffer.Length);
requestStream.Close();
HttpWebResponse httpWebResponse = (HttpWebResponse)webRequest.GetResponse();
using (StreamReader httpStreamReader = new StreamReader(httpWebResponse.GetResponseStream(), Encoding.GetEncoding("utf-8")))
{
responseContent = httpStreamReader.ReadToEnd();
}
httpWebResponse.Close();
webRequest.Abort();
return responseContent;
}
/// <summary>
/// 压缩字节
/// <author>黄磊</author>
/// <createDate>2019-04-11</createDate>
/// </summary>
/// <param name="bytes">待压缩字节</param>
/// <returns>压缩字节</returns>
public static byte[] CompressBytes(byte[] bytes)
{
using (MemoryStream compressStream = new MemoryStream())
{
using (var zipStream = new GZipStream(compressStream, CompressionMode.Compress))
zipStream.Write(bytes, 0, bytes.Length);
return compressStream.ToArray();
}
}
/// <summary>
/// 解压缩字节
/// </summary>
/// <param name="bytes">待解压缩字节</param>
/// <returns>解压缩字节</returns>
public static byte[] DeCompressBytes(byte[] bytes)
{
using (var compressStream = new MemoryStream(bytes))
{
using (var zipStream = new GZipStream(compressStream, CompressionMode.Decompress))
{
using (var resultStream = new MemoryStream())
{
zipStream.CopyTo(resultStream);
return resultStream.ToArray();
}
}
}
}
}
}这部分是我接口的代码(WebApi):
using APIs.EPC.FileManage.WebAPI.Entity.Entity;
using EPC.Common;
using EPC.FileManage.BLL.FileInfoManage;
using EPC.FileManage.Entity;
using PL.Base;
using System;
using System.Configuration;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web;
using System.Web.Http;
using System.Web.Script.Serialization;
namespace EPC.FileManage.Api.Controllers
{
/// <summary>
/// 文件上传接口
/// <author>Asa</author>
/// <createDate>2019-05-11</createDate>
/// </summary>
public class UploadFileController : BaseController
{
/// <summary>
/// 接收上传请求接口
/// <author>Asa</author>
/// <createDate>2018/09/11</createDate>
/// </summary>
/// <returns>返回详细的图片带访问前缀的URL</returns>
[HttpPost]
public HttpResponseMessage Save()
{
#region 读取与设置上传文件需要的配置
// 返回文件保存的地址
string returnSaveUrl = string.Empty;
// 设置文件上传的日期(用于创建保存地址使用)
string fileUploadDate = DateTime.Now.ToString("yyyyMMdd");
// 读取文件访问地址前缀
string fileUrlPrefix = ConfigurationManager.AppSettings["fileUrlPrefix"];
// 读取文件保存的文件夹配置
string fileSaveFolder = ConfigurationManager.AppSettings["fileSaveFolder"];
// 获取待上传文件文件名
string oldFileName = string.Empty;
// 获取待上传文件拓展名
string extensionName = string.Empty;
// 文件重命名
string fileNewName = string.Empty;
// 设置文件保存路径
string fileSavePath = HttpContext.Current.Server.MapPath("~\\" + fileSaveFolder + "\\" + fileUploadDate + "\\");
// 定义一个默认的图片类型数组
//string[] picTypeArray = { ".png", ".jpg", ".jpeg" };
// 定义一个HTTP响应对象
HttpResponseMessage httpResponseMessage = new HttpResponseMessage();
// 定义一个上传结果响应实体
EPC_UploadResponse epc_UploadResponse = new EPC_UploadResponse();
// 定义一个用于序列化的对象
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
// 判断存放上传文件的文件夹的配置是否为空
if (string.IsNullOrEmpty(fileSaveFolder))
{
epc_UploadResponse.StatusCode = 001;
epc_UploadResponse.Message = "缺少存放上传文件的文件夹配置";
httpResponseMessage.StatusCode = HttpStatusCode.OK;
httpResponseMessage.Content = new StringContent(javaScriptSerializer.Serialize(epc_UploadResponse));
return httpResponseMessage;
}
// 判断文件访问地址前缀配置是否为空
if (string.IsNullOrEmpty(fileUrlPrefix))
{
epc_UploadResponse.StatusCode = 001;
epc_UploadResponse.Message = "缺少文件访问地址前缀配置";
httpResponseMessage.StatusCode = HttpStatusCode.OK;
httpResponseMessage.Content = new StringContent(javaScriptSerializer.Serialize(epc_UploadResponse), Encoding.UTF8, "json");
return httpResponseMessage;
}
#endregion 读取与设置上传文件需要的配置
#region 保存文件到指定文件夹
// 判断保存文件的地址是否存在,如果不存在就创建该地址
if (!Directory.Exists(fileSavePath))
Directory.CreateDirectory(fileSavePath);
// 接收要上传的文件
HttpFileCollection files = HttpContext.Current.Request.Files;
var dateNow = HttpContext.Current.Request.Headers["dateNow"];
// 遍历文件集合,上传文件
foreach (string key in files.AllKeys)
{
try
{
// 定义一个上传文件相关信息实体类对象
EPC_UploadFileInfo epc_UploadFileInfo = new EPC_UploadFileInfo();
// 读取待上传的文件
HttpPostedFile waitUploadFile = files[key];
// 获取待上传文件的文件名
oldFileName = waitUploadFile.FileName;
// 获取待上传文件的拓展名
extensionName = Path.GetExtension(oldFileName);
// 待上传文件流
Stream waitUploadStream = waitUploadFile.InputStream;
// 待解压缩字节
byte[] waitDeCompressByte = Utiles.StreamToBytes(waitUploadStream);
// 已解压缩字节
byte[] DeCompressedByte = Utiles.DeCompressBytes(waitDeCompressByte);
// 文件重命名
fileNewName = DateTime.Now.ToString("yyyyMMddHHmmssfff") + extensionName;
// 执行保存图片到服务器的操作
File.WriteAllBytes(fileSavePath + fileNewName, DeCompressedByte);
// 返回文件保存路径
returnSaveUrl = (fileUrlPrefix + "/" + fileSaveFolder + "/" + fileUploadDate + "/" + fileNewName);
// 响应类赋值
epc_UploadResponse.StatusCode = 001;
epc_UploadResponse.Message = "文件上传成功";
epc_UploadResponse.FileName = oldFileName;
epc_UploadResponse.FileType = extensionName;
epc_UploadResponse.FileUrl = returnSaveUrl;
httpResponseMessage.StatusCode = HttpStatusCode.OK;
httpResponseMessage.Content = new StringContent(javaScriptSerializer.Serialize(epc_UploadResponse));
}
catch (Exception ex)
{
// 将文件保存失败错误写入日志
Log.Write("文件保存失败:" + ex.Message, "文件保存失败");
// 组装文件上传结果并返回
epc_UploadResponse.StatusCode = 002;
epc_UploadResponse.Message = "文件保存失败";
httpResponseMessage.StatusCode = HttpStatusCode.OK;
httpResponseMessage.Content = new StringContent(javaScriptSerializer.Serialize(epc_UploadResponse));
return httpResponseMessage;
}
}
#endregion 保存文件到指定文件夹
// 返回文件上传响应结果
return httpResponseMessage;
}
}
}这是我的响应实体类:
namespace EPC.FileManage.Entity
{
/// <summary>
/// 文件上传响应实体
/// <author>Asa</author>
/// <createDate>2019-0515</createDate>
/// </summary>
public class EPC_UploadResponse
{
/// <summary>
/// 状态码
/// </summary>
public int StatusCode { get; set; }
/// <summary>
/// 上传结果提示信息
/// </summary>
public string Message { get; set; }
/// <summary>
/// 逻辑文件名
/// </summary>
public string FileName { get; set; }
/// <summary>
/// 文件类型
/// </summary>
public string FileType { get; set; }
/// <summary>
/// 文件地址
/// </summary>
public string FileUrl { get; set; }
}
}这是最后运行的效果图:

点击开始上传按钮后:

上传之后还可以继续选择文件上传:
好了,一个完整的通过接口实现文件上传的功能就结束了,不过我发现plupload控件无法选择txt,docx文件,不知道是本身的bug还是我哪里写的有问题,正在研究中,有知道的小伙伴也可以告诉我一下,谢谢,感谢耐心看完的小伙伴们....
忘了附上需要的js和css了,抱歉,hahaha...
试了一下,js和css文件目前无法上传,如果有需要的话可以找我要,也可以自己去下载,不过展示界面就只能大家自己写了
50010702506256