tnblog
首页
视频
资源
登录

通过PlUpload控件配合WebApi接口完成压缩上传文件

5259人阅读 2019/5/27 16:31 总访问:78201 评论:1 收藏:0 手机
分类: 工具

          最近一段时间都在使用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文件目前无法上传,如果有需要的话可以找我要,也可以自己去下载,不过展示界面就只能大家自己写了


评价
a genius is the person who repeats the most times
排名
6
文章
6
粉丝
16
评论
8
{{item.articleTitle}}
{{item.blogName}} : {{item.content}}
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2024TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术