tnblog
首页
视频
资源
登录

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

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

          最近一段时间都在使用PlUpload做文件上传的功能,研究过后感觉使用起来体验还是比较好的,不过网上的资料很多都记录的很简便,故此记录一下,方便自己使用,也给需要的朋友提供多一个文件上传的选择。由于这篇文章比较长,我遇到坑的地方就不给大家一一举例了,要是小伙伴们想经历的话,可以先不看文章,自己去尝试一下。附上一篇中文介绍文档:https://www.cnblogs.com/2050/p/3913184.html;话不多说,直接上代码:

          这部分是我页面上的代码,由于为了方便使用,我的上传写成了一个用户控件,页面上只需要引用即可,UploadControl是引用控件的部分:

  1. <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="FileUpload.aspx.cs" Inherits="EPC.FileManager.Page.FileUpload" %>
  2. <%@ Register Src="~/UserControls/UploadControl.ascx" TagPrefix="uc1" TagName="UploadControl" %>
  3. <!DOCTYPE html>
  4. <html xmlns="http://www.w3.org/1999/xhtml">
  5. <head runat="server">
  6.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  7.     <title></title>
  8. </head>
  9. <body>
  10.     <form id="form1" runat="server">
  11.         <div>
  12.             <uc1:UploadControl runat="server" ID="UploadControl" />
  13.         </div>
  14.     </form>
  15. </body>
  16. </html>


          这一块是我的上传控件部分:

          首先是需要添加的引用:

  1. <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="UploadControl.ascx.cs" Inherits="EPC.FileManager.UserControls.UploadControl" %>
  2. <link href="../Themes/CSS/reset.css" rel="stylesheet" />
  3. <link href="../Themes/CSS/index.css" rel="stylesheet" />
  4. <script src="../Scripts/jQuery/jquery-1.11.1.min.js"></script>
  5. <script src="../Scripts/plupload/plupload.full.min.js"></script>
  6. <script src="../Scripts/jQuery/index.js"></script>
  7. <!--用于保存所有上传成功的文件的URL-->
  8. <input type="hidden" id="fileUploadUrl" runat="server" />

          然后是我的上传文件的界面布局,你们也可以自己更改为自己喜欢的风格,放上来只是为了便于讲解:

  1. <section class="center-box">
  2.     <div class="container">
  3.         <div class="center clearfix">
  4.             <div class="line-lebel">
  5.                 文件上传:
  6.             </div>
  7.             <div class="line-box">
  8.                 <!--上传下载开始-->
  9.                 <div class="J-upload-box clearfix">
  10.                     <div class="J-upload-area">
  11.                         <div class="J-need-upload-file clearfix">
  12.                             <div class="J-handle-btns">
  13.                                 <b class="J-continue-add" id="choseFileBtn"><i id="JcontinueAdd">选择文件</i>
  14.                                 </b>
  15.                                 <b class="J-to-upload" id="JToUpload">开始上传</b>
  16.                             </div>
  17.                         </div>
  18.                         <div class="J-show-the-name clearfix" style="display: none;">
  19.                             <!--选择文件和图片的时候 显示文件名-->
  20.                             <div class=" " id="JShowFileBox">
  21.                                 <div class="J-folding"><span>收起<i></i></span></div>
  22.                                 <ul class="J-file-img J-calc-len clearfix" id="JShowFileImg">
  23.                                     <%--<li title="J-folding.png">
  24.                                         <em>J-folding.png</em><span></span>
  25.                                     </li>--%>
  26.                                 </ul>
  27.                             </div>
  28.                             <!--只选择图片时-->
  29.                             <div class="J-imgs-box" id="JShowImgsBox">
  30.                                 <ul class="J-imgs J-calc-len clearfix" id="JShowImgs">
  31.                                     <%--<li title="2.jpg">
  32.                                         <em>
  33.                                             <img src="img/1.jpg"></em><span></span>
  34.                                     </li>   --%>
  35.                                 </ul>
  36.                             </div>
  37.                         </div>
  38.                     </div>
  39.                     <!--进度条-->
  40.                     <div class="ProgressBar" style="display: none">
  41.                         <div id="progress" style="width: 0%"></div>
  42.                     </div>
  43.                     <!--用户点击“开始上传”后的展示区域(已上传文件展示开始)-->
  44.                     <div class="J-show-all " id="JShowAll" style="display: none;">
  45.                         <div class="J-show-all-center">
  46.                             <div class="J-title" id="JTitle">已完成上传</div>
  47.                             <!--选择文件和图片的时候 显示文件名-->
  48.                             <div class="J-file-img-box ">
  49.                                 <div class="J-folding"><span>收起<i></i></span></div>
  50.                                 <ul class="J-file-img J-calc-len clearfix" id="JUploadFileImg">
  51.                                 </ul>
  52.                             </div>
  53.                             <!--只选择图片时-->
  54.                             <div class="J-imgs-box">
  55.                                 <ul class="J-imgs J-calc-len clearfix" id="JUploadImgs">
  56.                                 </ul>
  57.                             </div>
  58.                         </div>
  59.                     </div>
  60.                     <!--已上传文件展示结束-->
  61.                 </div>
  62.             </div>
  63.             <!--上传下载结束-->
  64.         </div>
  65.     </div>
  66. </section>


          界面效果是这样的,比较简陋,haha...:

          这个部分就是plupload控件的核心了,这个对象有许多的方法,大家可以根据自己的需求去研究和使用:

  1. <script>
  2.     // 实例化一个plupload上传对象,并根据需要进行相应的设置:
  3.     var uploader = new plupload.Uploader({
  4.         // 触发文件选择对话框的按钮,为哪个元素id
  5.         browse_button: 'choseFileBtn',
  6.         // 服务器端的上传页面地址,路径根据自己的实际情况配置
  7.         url: '../Handler/UploadHandler.ashx',
  8.         // swf文件,当需要使用swf方式进行上传时需要配置该参数
  9.         flash_swf_url: '../Scripts/plupload/moxie.swf',
  10.         // silverlight文件,当需要使用silverlight方式进行上传时需要配置该参数
  11.         silverlight_xap_url: '../Scripts/plupload/moxie.xap',
  12.         // 文件大小及类型相关设置
  13.         filters: {
  14.             // 最大只能上传200mb的文件
  15.             max_file_size: '200mb',
  16.             // 不允许队列中存在重复文件
  17.             prevent_duplicates: true,
  18.             // 允许上传的文件类型
  19.             mime_types: [{ title'FileTypes'extensions'doc,xls,xlsx,jpg,gif,png,jpeg,zip,rar' }]
  20.         }
  21.     });
  22.     
  23.     // 在实例对象上调用init()方法进行初始化
  24.     uploader.init();
  25.     // 文件上传前
  26.     uploader.bind('FilesAdded'function (uploader, files{
  27.         // 判断是否包含文件
  28.         var isFile = false;
  29.         // 判断是否包含图片
  30.         var isPic = false;
  31.         // 定义一个数组存放文件类型,这里我暂时还没想到怎么获取文件类型,所以用一个固定的代替,好像这个控件里面有些jQuery的函数使用不了,再研究下
  32.         var picTypeArr = ["image/png""image/jpeg""image/jpg"];
  33.         // 根据文件类型选择展示框     
  34.         for (var i = 0; i < files.length; i++) {
  35.             isPic = false;
  36.             // 获取文件类型
  37.             var fileType = files[i].type;
  38.             // 判断文件类型是图片还是文件(暂时指定数组中的三种类型为图片类型,其它默认为文件类型)
  39.             for (var j = 0; j < picTypeArr.length; j++) {
  40.                 if (picTypeArr[j] == fileType) {
  41.                     isPic = true;
  42.                 }
  43.             }
  44.             // 根据文件类型选择文件展示框
  45.             if (isPic == true) {
  46.                 // 拼接文件展示框HTML
  47.                 var html = '<li title="' + files[i].name + '" id="' + files[i].id + '"><em></em><span class="del_WaitUpload" FileId="' + files[i].id + '"></span></li>';
  48.                 // 展示待上传图片
  49.                 $("#JShowImgs").append(html);
  50.                 !function (i{
  51.                     // 图片预览(图片预览目前仅支持以上三种图片类型,大家可以再研究下其它图片类型怎么预览)
  52.                     previewImage(files[i], function (imgsrc{
  53.                         $('#' + files[i].id).find("em").append('<img class="imgZoom" src="' + imgsrc + '" />');
  54.                     })
  55.                 }(i);
  56.             } else {
  57.                 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>';
  58.                 // 展示待上传文件
  59.                 $("#JShowFileImg").append(html);
  60.             }
  61.         }
  62.         // 获取点击“开始上传”后待上传文件展示区域文件的个数
  63.         var waitUploadFileLiLen = $("#JShowFileImg").find('li').length;
  64.         var waitUploadPicLiLen = $("#JShowImgs").find("li").length;
  65.         // 待上传的文件如果不为空,展示待上传文件展示框,
  66.         if (waitUploadFileLiLen > 0 || waitUploadPicLiLen > 0) {
  67.             $(".J-show-the-name").show();
  68.         }
  69.         // 重新计算待上传的文件展示宽度(针对图片展示框),这个方法在index.js文件中
  70.         Funs.setImgWidth($("#JShowImgs li"));
  71.     });
  72.     // 文件上传过程中不断触发,用来显示上传进度
  73.     uploader.bind('UploadProgress'function (uploader, file{
  74.         // 禁用选择文件和开始上传按钮
  75.         $("#choseFileBtn").attr("disabled"true);
  76.         $("#JToUpload").attr("disabled"true);
  77.         // 展示进度条(这个进度条是随意写的,大家可以自行替换为自己想要的效果)
  78.         uploadProcess(file.percent);
  79.     });
  80.     // 当队列中的某一个文件正要开始上传前触发
  81.     uploader.bind('BeforeUpload'function (uploader, file{
  82.         // 禁用选择文件和开始上传按钮
  83.         $("#choseFileBtn").attr("disabled"true);
  84.         $("#JToUpload").attr("disabled"true);
  85.         // 清理进度条
  86.         clearProcess();
  87.     });
  88.     // 队列中的某一个文件上传完成后触发
  89.     uploader.bind('FileUploaded'function (uploader, file, responseObject{
  90.         // 接收上传响应信息
  91.         var resp = JSON.parse(responseObject.response)
  92.         // 判断上传是否成功
  93.         if (resp.StatusCode == 1) {
  94.             // 判断是否包含图片
  95.             var isPic = false;
  96.             // 定义两个数组存放文件类型
  97.             var picTypeArr = [".png"".jpeg"".jpg"];
  98.             // 判断文件类型是图片还是文件
  99.             for (var j = 0; j < picTypeArr.length; j++) {
  100.                 //isPic = false;
  101.                 if (picTypeArr[j] == resp.FileType) {
  102.                     isPic = true;
  103.                 }
  104.             }
  105.             // 根据文件类型选择展示框
  106.             if (isPic == true) {
  107.                 // 上传成功,展示已上传图片
  108.                 var html = '<li title="' + resp.FileName + '"><em><img src="' + resp.FileUrl + '"></em><span class="del_Uploaded" fileurl="' + resp.FileUrl + '"></span></li>';
  109.                 $("#JUploadImgs").append(html);
  110.             }
  111.             else {
  112.                 // 上传成功,展示已上传文件
  113.                 var html = '<li title="' + resp.FileName + '" ><em><a href="' + resp.FileUrl + '">' + resp.FileName + '</a></em><span class="del_Uploaded" fileurl="' + resp.FileUrl + '"></span></li>';
  114.                 // 展示已完成上传文件
  115.                 $("#JUploadFileImg").append(html);
  116.             }
  117.             // 判断已上传文件展示框是否为空,不为空则展示
  118.             var uploadFileLiLen = $("#JUploadFileImg").find("li").length;
  119.             var uploadPicLiLen = $("#JUploadImgs").find("li").length;
  120.             if (uploadFileLiLen > 0 || uploadPicLiLen > 0) {
  121.                 // 展示已上传文件展示框
  122.                 $("#JShowAll").show();
  123.                 // 清除进度条并隐藏
  124.                 clearProcess();
  125.                 // 删除上传队列中文件(注意:上传成功后必须移除uploader对象中的文件,否则会对之后的上传功能造成影响)
  126.                 uploader.removeFile(file);
  127.                 // 移除对应的待上传文件展示框li
  128.                 $("#" + file.id + "").remove();
  129.                 // 判断待上传文件展示框是否为空,为空则隐藏
  130.                 var waitUploadFileLiLen = $("#JShowFileImg").find('li').length;
  131.                 var waitUploadPicLiLen = $("#JShowImgs").find("li").length;
  132.                 if (waitUploadFileLiLen == 0 && waitUploadPicLiLen == 0) {
  133.                     // 隐藏待上传文件展示框
  134.                     $(".J-show-the-name").hide();
  135.                 }
  136.                 // 保存已上传文件的URL
  137.                 var fileUrl = $("#UploadControl_fileUploadUrl").val();
  138.                 if (fileUrl != null && fileUrl != "") {
  139.                     $("#UploadControl_fileUploadUrl").val($("#UploadControl_fileUploadUrl").val() + "," + resp.FileUrl)
  140.                 }
  141.                 else {
  142.                     $("#UploadControl_fileUploadUrl").val(resp.FileUrl)
  143.                 }
  144.             }
  145.         }
  146.         else {
  147.             // 弹出上传失败的提示信息
  148.             alert(resp.Message);
  149.             clearProcess();
  150.             return;
  151.         }
  152.     });
  153.     // 当上传队列中所有文件都上传完成后触发
  154.     uploader.bind('UploadComplete'function (uploader, files{
  155.         // 取消禁用选择文件和开始上传按钮
  156.         $("#upload-btn-add").attr("disabled"false);
  157.         $(".upload-btn").attr("disabled"false);
  158.         // 删除已上传文件
  159.         $(".del_Uploaded").click(function ({
  160.             // 移除当前被删除文件的URL
  161.             var fileDelUrl = $(this).attr("fileurl");
  162.             var uploadArray = $("#UploadControl_fileUploadUrl").val().split(',');
  163.             for (var i = 0; i < uploadArray.length; i++) {
  164.                 if (uploadArray[i] == fileDelUrl) {
  165.                     uploadArray.splice(i, 1);
  166.                 }
  167.             }
  168.             // 将保存上传文件URL的input重赋值
  169.             $("#UploadControl_fileUploadUrl").val(uploadArray);
  170.             // 移除删除文件的li
  171.             $(this).parent().remove();
  172.             // 判断ul是否为空
  173.             var uploadFileLiLen = $("#JUploadFileImg").find("li").length;
  174.             var uploadPicLiLen = $("#JUploadImgs").find("li").length;
  175.             if (uploadFileLiLen == 0 && uploadPicLiLen == 0) {
  176.                 $("#JShowAll").hide();
  177.             }
  178.         });
  179.     });
  180.     // 当上传出错时触发
  181.     uploader.bind('Error'function (uploader, errObject{
  182.         //每个事件监听函数都会传入一些很有用的参数,
  183.         //我们可以利用这些参数提供的信息来做比如更新UI,提示上传进度等操作
  184.     });
  185.     //最后给"开始上传"按钮注册事件
  186.     document.getElementById('JToUpload').onclick = function ({
  187.         //调用实例对象的start()方法开始上传文件,当然你也可以在其他地方调用该方法
  188.         uploader.start();
  189.     }
  190.     // 删除待上传队列中的文件
  191.     $("#JShowFileImg,#JShowImgs").on('click''.del_WaitUpload'function (e{
  192.         // 获取想要删除的上传队列文件的ID
  193.         var FileId = $(this).attr("FileId");
  194.         // 根据文件ID获取想要删除的文件
  195.         var file = uploader.getFile(FileId);
  196.         // 从uploader对象中移除目标文件
  197.         uploader.removeFile(file);
  198.         // 同时移除展示文件的li
  199.         $(this).parent().remove();
  200.         // 获取待上传文件的数量
  201.         var waitUploadFileLiLen = $("#JShowFileImg").find('li').length;
  202.         var waitUploadPicLiLen = $("#JShowImgs").find("li").length;
  203.         if (waitUploadFileLiLen == 0 && waitUploadPicLiLen == 0) {
  204.             $(".J-show-the-name").hide();
  205.         }
  206.         // 重新计算未上传的文件展示宽度
  207.         Funs.setImgWidth($("#JShowImgs li"));
  208.     });
  209.     // 上传进度条显示
  210.     function uploadProcess(t{
  211.         // 展示进度条
  212.         $(".ProgressBar").show();
  213.         // 进度条百分比框
  214.         var jindutiao = document.getElementById("progress");
  215.         jindutiao.style.width = t + "%";
  216.         jindutiao.innerHTML = jindutiao.style.width;
  217.     }
  218.     // 清理进度条框文本并隐藏进度条
  219.     function clearProcess({
  220.         var jindutiao = document.getElementById("progress");
  221.         jindutiao.style.width = "0%";
  222.         jindutiao.innerHTML = "0%";
  223.         // 隐藏进度条
  224.         $(".ProgressBar").hide();
  225.     }
  226.     // 图片预览
  227.     function previewImage(file, callback{
  228.         if (!file || !/image\//.test(file.type)) return;
  229.         if (file.type == 'image/gif') {
  230.             var fr = new mOxie.FileReader();
  231.             fr.onload = function ({
  232.                 callback(fr.result);
  233.                 fr.destroy();
  234.                 fr = null;
  235.             }
  236.             fr.readAsDataURL(file.getSource());
  237.         } else {
  238.             var img = new moxie.image.Image();
  239.             img.load(file.getSource());
  240.             img.onload = function ({
  241.                 img.downsize(300300);// 压缩要预览的图片,宽300,高300
  242.                 var imgsrc = img.type == 'image/jpeg' ? img.getAsDataURL('image/jpeg'90) : img.getAsDataURL(); // 得到图片src,base64编码的数据
  243.                 callback && callback(imgsrc); // callback传入的参数为预览图片的url
  244.                 img.destroy();
  245.                 img = null;
  246.             };
  247.         }
  248.     }
  249.     </script>

          

          接下来是我后台的代码,如果只是想了解plupload控件的朋友就可以不用看下去了,这些算是我自己对自己的一个总结:

          这是我handler的部分,主要是接收控件传进来的文件并传入文件上传方法及返回上传结果:

  1. using EPC.Components.FileManage;
  2. using EPC.FileManage.Entity;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Web;
  7. using System.Web.Script.Serialization;
  8. namespace EPC.FileManager.Handler
  9. {
  10.     /// <summary>
  11.     /// UploadHandler 的摘要说明
  12.     /// </summary>
  13.     public class UploadHandler : IHttpHandler
  14.     {
  15.         /// <summary>
  16.         /// 文件上传
  17.         /// <author>Asa</author>
  18.         /// <createDate>2019-05-01</createDate>
  19.         /// </summary>
  20.         /// <param name="context">http上下文对象</param>
  21.         public void ProcessRequest(HttpContext context)
  22.         {
  23.             context.Response.ContentType = "text/plain";
  24.             context.Response.Clear();
  25.             // 声明一个用于序列化的对象
  26.             JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
  27.             // 判断待上传文件是否为空
  28.             if (context.Request.Files.Count > 0)
  29.             {
  30.                 for (int i = 0; i < context.Request.Files.Count; i++)
  31.                 {
  32.                     // 接收待上传的文件对象
  33.                     HttpPostedFile file = HttpContext.Current.Request.Files[i];
  34.                     // 调用上传文件的方法
  35.                     EPC_UploadResponse epc_UploadResponse = EPC_FileManage.UploadFile(file);
  36.                     // 返回上传结果
  37.                     HttpContext.Current.Response.Write(javaScriptSerializer.Serialize(epc_UploadResponse));
  38.                 }
  39.             }
  40.         }
  41.         public bool IsReusable
  42.         {
  43.             get
  44.             {
  45.                 return false;
  46.             }
  47.         }
  48.     }
  49. }


          这一块是我上传方法的部分:

  1. using EPC.Common;
  2. using EPC.FileManage.Entity;
  3. using System;
  4. using System.Configuration;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Web;
  8. using System.Web.Script.Serialization;
  9. namespace EPC.Components.FileManage
  10. {
  11.     /// <summary>
  12.     /// EPC文件管理类
  13.     /// <author>Asa</author>
  14.     /// <createDate>2019-05-15</createDate>
  15.     /// </summary>
  16.     public class EPC_FileManage
  17.     {
  18.         public static EPC_UploadResponse UploadFile(HttpPostedFile file)
  19.         {
  20.             #region 读取文件上传相关配置,定义文件上传所需变量--BEGIN
  21.             // 定义一个变量接收待上传文件名称
  22.             string fileName = string.Empty;
  23.             // 定义一个变量接收待上传文件类型
  24.             string fileType = string.Empty;
  25.             // 读取允许上传的文件类型配置
  26.             string allowedFileType = ConfigurationManager.AppSettings["allowedFileType"];
  27.             // 定义一个数组接收允许上传的文件类型
  28.             string[] allowedFileTypeArray = null;
  29.             // 读取允许上传的文件大小(KB)
  30.             string allowedFileSizeStr = ConfigurationManager.AppSettings["allowedFileSize"];
  31.             // 定义一个变量接收转换为int类型的allowedFileSize
  32.             int allowedFileSizeInt = 0;
  33.             // 读取API请求地址前缀
  34.             string apiUrlPrefix = ConfigurationManager.AppSettings["apiUrlPrefix"];
  35.             // 定义一个变量拼接完整的接口请求地址
  36.             string apiFullUrl = string.Empty;
  37.             // 创建一个上传结果响应类对象
  38.             EPC_UploadResponse epcUploadResponse = new EPC_UploadResponse();
  39.             // 定义一个用于反序列化的对象
  40.             JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
  41.             #endregion 读取文件上传相关配置,定义文件上传所需变量--END
  42.             #region 判断文件上传相关配置是否合法及上传文件是否为空--BEGIN
  43.             // 判断允许上传的文件类型配置是否为空
  44.             if (string.IsNullOrEmpty(allowedFileType))
  45.             {
  46.                 epcUploadResponse.StatusCode = 001;
  47.                 epcUploadResponse.Message = "上传失败:缺少允许上传的文件类型配置";
  48.                 return epcUploadResponse;
  49.             }
  50.             // 判断允许上传的文件大小配置是否为空
  51.             if (string.IsNullOrEmpty(allowedFileSizeStr))
  52.             {
  53.                 epcUploadResponse.StatusCode = 001;
  54.                 epcUploadResponse.Message = "上传失败:缺少允许上传的文件大小配置";
  55.                 return epcUploadResponse;
  56.             }
  57.             // 判断API请求地址前缀配置是否为空
  58.             if (string.IsNullOrEmpty(apiUrlPrefix))
  59.             {
  60.                 epcUploadResponse.StatusCode = 001;
  61.                 epcUploadResponse.Message = "上传失败:缺少请求API的地址前缀配置";
  62.                 return epcUploadResponse;
  63.             }
  64.             // 判断待上传文件是否为空。
  65.             if (file == null)
  66.             {
  67.                 epcUploadResponse.StatusCode = 001;
  68.                 epcUploadResponse.Message = "上传失败:缺少文件";
  69.                 return epcUploadResponse;
  70.             }
  71.             #endregion 判断文件上传相关配置是否合法及上传文件是否为空--END
  72.             #region 判断文件格式和大小是否符合规则--BEGIN
  73.             // 接收允许上传的文件类型
  74.             try
  75.             {
  76.                 allowedFileTypeArray = allowedFileType.Split(',');
  77.             }
  78.             catch
  79.             {
  80.                 epcUploadResponse.StatusCode = 001;
  81.                 epcUploadResponse.Message = "上传失败:允许上传文件类型配置不合法";
  82.                 return epcUploadResponse;
  83.             }
  84.             // 接收允许上传的文件大小
  85.             try
  86.             {
  87.                 allowedFileSizeInt = Convert.ToInt32(allowedFileSizeStr);
  88.             }
  89.             catch
  90.             {
  91.                 epcUploadResponse.StatusCode = 001;
  92.                 epcUploadResponse.Message = "上传失败:允许上传文件大小配置不合法";
  93.                 return epcUploadResponse;
  94.             }
  95.             // 获取待上传文件的文件名
  96.             fileName = file.FileName;
  97.             // 获取待上传文件的类型
  98.             fileType = Path.GetExtension(fileName);
  99.             // 判断文件类型是否合法
  100.             if (!allowedFileTypeArray.Contains(fileType))
  101.             {
  102.                 epcUploadResponse.StatusCode = 001;
  103.                 epcUploadResponse.Message = "上传失败:‘" + fileType + "’文件格式不合法" + allowedFileTypeArray + "";
  104.                 return epcUploadResponse;
  105.             }
  106.             // 判断允许上传的文件大小是否超过默认最大值
  107.             if ((allowedFileSizeInt / 1024) <= 200)
  108.             {
  109.                 if ((file.ContentLength / 1024) > allowedFileSizeInt)
  110.                 {
  111.                     epcUploadResponse.StatusCode = 001;
  112.                     epcUploadResponse.Message = "上传失败:‘" + (file.ContentLength / 1024) + "kb’文件大小不合法";
  113.                     return epcUploadResponse;
  114.                 }
  115.             }
  116.             else
  117.             {
  118.                 if ((file.ContentLength / 1024 / 1024) > 200)
  119.                 {
  120.                     epcUploadResponse.StatusCode = 001;
  121.                     epcUploadResponse.Message = "上传失败:‘" + (file.ContentLength / 1024 / 1024) + "kb’文件大小不合法";
  122.                     return epcUploadResponse;
  123.                 }
  124.             }
  125.             #endregion 判断文件格式和大小是否符合规则--END
  126.             #region API接口方式上传
  127.             try
  128.             {
  129.                 // API请求地址
  130.                 apiFullUrl = apiUrlPrefix + "/" + "API/UploadFile/Save";
  131.                 // 待上传文件流                         
  132.                 Stream waitUploadStream = file.InputStream;
  133.                 // 待压缩字节
  134.                 byte[] waitCompressByte = Utiles.StreamToBytes(waitUploadStream);
  135.                 // 已压缩字节
  136.                 byte[] compressedByte = Utiles.CompressBytes(waitCompressByte);
  137.                 // 待上传文件流 
  138.                 waitUploadStream = Utiles.BytesToStream(compressedByte);
  139.                 // 接收文件上传返回结果
  140.                 string uploadResponse = Utiles.HttpPostUpload(apiFullUrl, file.FileName, waitUploadStream);
  141.                 // 反序列化响应结果并赋值给文件上传响应实体
  142.                 epcUploadResponse = javaScriptSerializer.Deserialize<EPC_UploadResponse>(uploadResponse);
  143.             }
  144.             catch (Exception ex)
  145.             {
  146.                 epcUploadResponse.StatusCode = 002;
  147.                 epcUploadResponse.Message = "文件上传失败:无法连接到服务器";
  148.                 return epcUploadResponse;
  149.             }
  150.             #endregion
  151.             // 返回上传结果响应类
  152.             return epcUploadResponse;
  153.         }
  154.     }
  155. }

          

          这部分是我的公共方法代码:

  1. using System;
  2. using System.IO;
  3. using System.IO.Compression;
  4. using System.Net;
  5. using System.Text;
  6. namespace EPC.Common
  7. {
  8.     /// <summary>
  9.     /// 文件管理系统工具类
  10.     /// <author>Asa</author>
  11.     /// <createDate>20190507</createDate>
  12.     /// </summary>
  13.     public class Utiles
  14.     {
  15.         /// <summary>
  16.         /// 文件流转字节
  17.         /// </summary>
  18.         /// <author>Asa</author>
  19.         /// <createDate>20190507</createDate>
  20.         /// <param name="stream">文件流</param>
  21.         /// <returns></returns>
  22.         public static byte[] StreamToBytes(Stream stream)
  23.         {
  24.             byte[] array = new byte[stream.Length];
  25.             stream.Seek(0L, SeekOrigin.Begin);
  26.             stream.Read(array, 0, array.Length);
  27.             stream.Close();
  28.             return array;
  29.         }
  30.         /// <summary>
  31.         /// 将字节转为文件流
  32.         /// </summary>
  33.         /// <author>Asa</author>
  34.         /// <createDate>20190507</createDate>
  35.         /// <param name="stream">字节</param>
  36.         /// <returns></returns>
  37.         public static Stream BytesToStream(byte[] bytes)
  38.         {
  39.             return new MemoryStream(bytes);
  40.         }
  41.         /// <summary>
  42.         /// 模拟POST提交上传请求
  43.         /// <author>Asa</author>
  44.         /// <createDate>20190507</createDate>
  45.         /// </summary>
  46.         /// <param name="url">自定义请求url</param>
  47.         /// <param name="fileName">上传的文件名</param>
  48.         /// <param name="stream"></param>
  49.         /// <param name="timeOut">超时时间[暂未使用]</param>
  50.         /// <returns>返回字符串类型</returns>
  51.         public static string HttpPostUpload(string url, string fileName, Stream stream, int timeOut = 0)
  52.         {
  53.             // 定义一个相应内容对象
  54.             string responseContent;
  55.             // 定义一个内存流对象(用于接收待上传文件)
  56.             MemoryStream memStream = new MemoryStream();
  57.             // 定义一个发送自定义post请求的对象
  58.             HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
  59.             // 边界符
  60.             string boundary = "----WebKitFormBoundaryut99VQ34SOB8NU0X\r\n";
  61.             // 边界符
  62.             byte[] beginBoundary = Encoding.ASCII.GetBytes("--" + boundary);
  63.             // 最后的结束符
  64.             byte[] endBoundary = Encoding.ASCII.GetBytes("------WebKitFormBoundaryut99VQ34SOB8NU0X--\r\n");
  65.             // 设置属性
  66.             webRequest.Method = "POST";
  67.             webRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
  68.             webRequest.ContentType = "multipart/form-data; boundary=" + boundary;
  69.             // 开始时间参数(你可以把你需要的参数写在请求头里面传进接口)
  70.             string dateNow = DateTime.Now.ToString("yyyyMMdd");
  71.             webRequest.Headers.Add("dateNow", dateNow);
  72.             // 写入文件
  73.             const string filePartHeader =
  74.                 "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\";\r\n" + "datenow=\"{2}\"\r\n" +
  75.                 "Content-Type: application/octet-stream\r\n\r\n";
  76.             string header = string.Format(filePartHeader, "file", fileName, dateNow);
  77.             byte[] headerbytes = Encoding.UTF8.GetBytes(header);
  78.             memStream.Write(beginBoundary, 0, beginBoundary.Length);
  79.             memStream.Write(headerbytes, 0, headerbytes.Length);
  80.             // 将文件流转换为字节
  81.             byte[] temp = StreamToBytes(stream);
  82.             // 将字节写入内存流
  83.             memStream.Write(temp, 0, temp.Length);
  84.             byte[] tt = Encoding.UTF8.GetBytes("\r\n");
  85.             memStream.Write(tt, 0, tt.Length);
  86.             // Key-Value数据
  87.             var stringKeyHeader = "--" + boundary +
  88.                                   "\r\nContent-Disposition: form-data; name=\"{0}\"" +
  89.                                   "\r\n\r\n{1}\r\n";
  90.             // 写入最后的结束边界符
  91.             memStream.Write(endBoundary, 0, endBoundary.Length);
  92.             Stream requestStream = webRequest.GetRequestStream();
  93.             StreamWriter myStreamWriter = new StreamWriter(requestStream, Encoding.GetEncoding("utf-8"));
  94.             memStream.Position = 0;
  95.             byte[] tempBuffer = new byte[memStream.Length];
  96.             memStream.Read(tempBuffer, 0, tempBuffer.Length);
  97.             memStream.Close();
  98.             requestStream.Write(tempBuffer, 0, tempBuffer.Length);
  99.             requestStream.Close();
  100.             HttpWebResponse httpWebResponse = (HttpWebResponse)webRequest.GetResponse();
  101.             using (StreamReader httpStreamReader = new StreamReader(httpWebResponse.GetResponseStream(), Encoding.GetEncoding("utf-8")))
  102.             {
  103.                 responseContent = httpStreamReader.ReadToEnd();
  104.             }
  105.             httpWebResponse.Close();
  106.             webRequest.Abort();
  107.             return responseContent;
  108.         }
  109.         /// <summary>
  110.         /// 压缩字节
  111.         /// <author>黄磊</author>
  112.         /// <createDate>2019-04-11</createDate>
  113.         /// </summary>
  114.         /// <param name="bytes">待压缩字节</param>
  115.         /// <returns>压缩字节</returns>
  116.         public static byte[] CompressBytes(byte[] bytes)
  117.         {
  118.             using (MemoryStream compressStream = new MemoryStream())
  119.             {
  120.                 using (var zipStream = new GZipStream(compressStream, CompressionMode.Compress))
  121.                     zipStream.Write(bytes, 0, bytes.Length);
  122.                 return compressStream.ToArray();
  123.             }
  124.         }
  125.         /// <summary>
  126.         /// 解压缩字节
  127.         /// </summary>
  128.         /// <param name="bytes">待解压缩字节</param>
  129.         /// <returns>解压缩字节</returns>
  130.         public static byte[] DeCompressBytes(byte[] bytes)
  131.         {
  132.             using (var compressStream = new MemoryStream(bytes))
  133.             {
  134.                 using (var zipStream = new GZipStream(compressStream, CompressionMode.Decompress))
  135.                 {
  136.                     using (var resultStream = new MemoryStream())
  137.                     {
  138.                         zipStream.CopyTo(resultStream);
  139.                         return resultStream.ToArray();
  140.                     }
  141.                 }
  142.             }
  143.         }
  144.     }
  145. }


          这部分是我接口的代码(WebApi):

  1. using APIs.EPC.FileManage.WebAPI.Entity.Entity;
  2. using EPC.Common;
  3. using EPC.FileManage.BLL.FileInfoManage;
  4. using EPC.FileManage.Entity;
  5. using PL.Base;
  6. using System;
  7. using System.Configuration;
  8. using System.IO;
  9. using System.Net;
  10. using System.Net.Http;
  11. using System.Text;
  12. using System.Web;
  13. using System.Web.Http;
  14. using System.Web.Script.Serialization;
  15. namespace EPC.FileManage.Api.Controllers
  16. {
  17.     /// <summary>
  18.     /// 文件上传接口
  19.     /// <author>Asa</author>
  20.     /// <createDate>2019-05-11</createDate>
  21.     /// </summary>
  22.     public class UploadFileController : BaseController
  23.     {
  24.         /// <summary>
  25.         /// 接收上传请求接口
  26.         /// <author>Asa</author>
  27.         /// <createDate>2018/09/11</createDate>
  28.         /// </summary>
  29.         /// <returns>返回详细的图片带访问前缀的URL</returns>
  30.         [HttpPost]
  31.         public HttpResponseMessage Save()
  32.         {
  33.             #region 读取与设置上传文件需要的配置
  34.             // 返回文件保存的地址
  35.             string returnSaveUrl = string.Empty;
  36.             // 设置文件上传的日期(用于创建保存地址使用)
  37.             string fileUploadDate = DateTime.Now.ToString("yyyyMMdd");
  38.             // 读取文件访问地址前缀
  39.             string fileUrlPrefix = ConfigurationManager.AppSettings["fileUrlPrefix"];
  40.             // 读取文件保存的文件夹配置
  41.             string fileSaveFolder = ConfigurationManager.AppSettings["fileSaveFolder"];
  42.             // 获取待上传文件文件名
  43.             string oldFileName = string.Empty;
  44.             // 获取待上传文件拓展名
  45.             string extensionName = string.Empty;
  46.             // 文件重命名
  47.             string fileNewName = string.Empty;
  48.             // 设置文件保存路径
  49.             string fileSavePath = HttpContext.Current.Server.MapPath("~\\" + fileSaveFolder + "\\" + fileUploadDate + "\\");
  50.             // 定义一个默认的图片类型数组
  51.             //string[] picTypeArray = { ".png", ".jpg", ".jpeg" };
  52.             // 定义一个HTTP响应对象
  53.             HttpResponseMessage httpResponseMessage = new HttpResponseMessage();
  54.             // 定义一个上传结果响应实体
  55.             EPC_UploadResponse epc_UploadResponse = new EPC_UploadResponse();
  56.             // 定义一个用于序列化的对象
  57.             JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
  58.             // 判断存放上传文件的文件夹的配置是否为空
  59.             if (string.IsNullOrEmpty(fileSaveFolder))
  60.             {
  61.                 epc_UploadResponse.StatusCode = 001;
  62.                 epc_UploadResponse.Message = "缺少存放上传文件的文件夹配置";
  63.                 httpResponseMessage.StatusCode = HttpStatusCode.OK;
  64.                 httpResponseMessage.Content = new StringContent(javaScriptSerializer.Serialize(epc_UploadResponse));
  65.                 return httpResponseMessage;
  66.             }
  67.             // 判断文件访问地址前缀配置是否为空
  68.             if (string.IsNullOrEmpty(fileUrlPrefix))
  69.             {
  70.                 epc_UploadResponse.StatusCode = 001;
  71.                 epc_UploadResponse.Message = "缺少文件访问地址前缀配置";
  72.                 httpResponseMessage.StatusCode = HttpStatusCode.OK;
  73.                 httpResponseMessage.Content = new StringContent(javaScriptSerializer.Serialize(epc_UploadResponse), Encoding.UTF8, "json");
  74.                 return httpResponseMessage;
  75.             }
  76.             #endregion 读取与设置上传文件需要的配置
  77.             #region 保存文件到指定文件夹
  78.             // 判断保存文件的地址是否存在,如果不存在就创建该地址
  79.             if (!Directory.Exists(fileSavePath))
  80.                 Directory.CreateDirectory(fileSavePath);
  81.             // 接收要上传的文件
  82.             HttpFileCollection files = HttpContext.Current.Request.Files;
  83.             var dateNow = HttpContext.Current.Request.Headers["dateNow"];
  84.             // 遍历文件集合,上传文件
  85.             foreach (string key in files.AllKeys)
  86.             {
  87.                 try
  88.                 {
  89.                     // 定义一个上传文件相关信息实体类对象
  90.                     EPC_UploadFileInfo epc_UploadFileInfo = new EPC_UploadFileInfo();
  91.                     // 读取待上传的文件
  92.                     HttpPostedFile waitUploadFile = files[key];
  93.                     // 获取待上传文件的文件名
  94.                     oldFileName = waitUploadFile.FileName;
  95.                     // 获取待上传文件的拓展名
  96.                     extensionName = Path.GetExtension(oldFileName);
  97.                     // 待上传文件流                         
  98.                     Stream waitUploadStream = waitUploadFile.InputStream;
  99.                     // 待解压缩字节
  100.                     byte[] waitDeCompressByte = Utiles.StreamToBytes(waitUploadStream);
  101.                     // 已解压缩字节
  102.                     byte[] DeCompressedByte = Utiles.DeCompressBytes(waitDeCompressByte);
  103.                     // 文件重命名
  104.                     fileNewName = DateTime.Now.ToString("yyyyMMddHHmmssfff") + extensionName;
  105.                     // 执行保存图片到服务器的操作
  106.                     File.WriteAllBytes(fileSavePath + fileNewName, DeCompressedByte);
  107.                     // 返回文件保存路径
  108.                     returnSaveUrl = (fileUrlPrefix + "/" + fileSaveFolder + "/" + fileUploadDate + "/" + fileNewName);
  109.                     // 响应类赋值
  110.                     epc_UploadResponse.StatusCode = 001;
  111.                     epc_UploadResponse.Message = "文件上传成功";
  112.                     epc_UploadResponse.FileName = oldFileName;
  113.                     epc_UploadResponse.FileType = extensionName;
  114.                     epc_UploadResponse.FileUrl = returnSaveUrl;
  115.                     httpResponseMessage.StatusCode = HttpStatusCode.OK;
  116.                     httpResponseMessage.Content = new StringContent(javaScriptSerializer.Serialize(epc_UploadResponse));
  117.                 }
  118.                 catch (Exception ex)
  119.                 {
  120.                     // 将文件保存失败错误写入日志
  121.                     Log.Write("文件保存失败:" + ex.Message, "文件保存失败");
  122.                     // 组装文件上传结果并返回
  123.                     epc_UploadResponse.StatusCode = 002;
  124.                     epc_UploadResponse.Message = "文件保存失败";
  125.                     httpResponseMessage.StatusCode = HttpStatusCode.OK;
  126.                     httpResponseMessage.Content = new StringContent(javaScriptSerializer.Serialize(epc_UploadResponse));
  127.                     return httpResponseMessage;
  128.                 }
  129.             }
  130.             #endregion 保存文件到指定文件夹
  131.             // 返回文件上传响应结果
  132.             return httpResponseMessage;
  133.         }
  134.     }
  135. }


          这是我的响应实体类:

  1. namespace EPC.FileManage.Entity
  2. {
  3.     /// <summary>
  4.     /// 文件上传响应实体
  5.     /// <author>Asa</author>
  6.     /// <createDate>2019-0515</createDate>
  7.     /// </summary>
  8.     public class EPC_UploadResponse
  9.     {
  10.         /// <summary>
  11.         /// 状态码
  12.         /// </summary>
  13.         public int StatusCode { getset; }
  14.         /// <summary>
  15.         /// 上传结果提示信息
  16.         /// </summary>
  17.         public string Message { getset; }
  18.         /// <summary>
  19.         /// 逻辑文件名
  20.         /// </summary>
  21.         public string FileName { getset; }
  22.         /// <summary>
  23.         /// 文件类型
  24.         /// </summary>
  25.         public string FileType { getset; }
  26.         /// <summary>
  27.         /// 文件地址
  28.         /// </summary>
  29.         public string FileUrl { getset; }
  30.     }
  31. }


          这是最后运行的效果图:

        

 

          点击开始上传按钮后:

          上传之后还可以继续选择文件上传:

  

          好了,一个完整的通过接口实现文件上传的功能就结束了,不过我发现plupload控件无法选择txt,docx文件,不知道是本身的bug还是我哪里写的有问题,正在研究中,有知道的小伙伴也可以告诉我一下,谢谢,感谢耐心看完的小伙伴们....






          忘了附上需要的js和css了,抱歉,hahaha...

          试了一下,js和css文件目前无法上传,如果有需要的话可以找我要,也可以自己去下载,不过展示界面就只能大家自己写了


评价

剑轩

2019/5/27 17:07:56

[good][good]厉害了,这个很实用。这个可以实现图片压缩?

通过url传递一个带井号()的参数并正确获取

正常情况下支持通过url是不能传递#等特殊符号的但是可以通过url编码解码解决通过url传递参数时某些特殊符号不能传递的问题n...

rabbitmq官网上六大版块之二(Direct类型交换机通过routingKey分类型输出)

其实rabbitmq,老师都说得差不多了,下面是老师的连接。http://www.tnblog.net/aojiancc2/article/UserCategory/134官网教...

通过Windows服务进行FTP与服务器之间文件的传输

这几天做了一个关于FTP与服务器之间文件互相传输的Windows服务,本地开发的时候非常顺利,很快就开发完成了,可是将服务部...

.net core 通过不同Accept访问同方法请求不同方法处理

1.对于自定义的Accept需要进行注册比如我这里的application/vnd.cgzl.hateoas+jsonservices.AddMvc(option=&gt; { option...

.netcore 通过Flurl验证k8s内部访问与获取环境变量

.netcore验证k8s内部访问与获取环境变量[TOC] 创建k8s-name项目 项目结构如下 实验过程 st=>start: k8s-demo项...

.netcore 通过Flurl验证k8s内部访问与获取环境变量 (二)

.netcore验证k8s内部访问与获取环境变量 (二)[TOC] 修改k8s-name项目 NameController.cs [ApiController] ...

consul 无法通过ip访问

consul agent -dev 只能本地可以访问要想通过ip可以访问,使用下面的使用即可consul agent -dev -client 0.0.0.0 -ui 指定...

Python中通过fake_useragent生成随机UserAgent

fake_useragent第三方库,来实现随机请求头的设置;GitHub ---&gt; https://github.com/hellysmile/fake-useragent安...

js与后台通过json传递对象

原理图解:前台:&lt;!DOCTYPEhtml&gt; &lt;html&gt; &lt;head&gt; &lt;metacharset=&quot;utf-8&quot;/&gt; &lt;title...

sqlsugar 对接mysql分表。sqlsguar分表注意事项。分表思路,通过日期获取分表表名等

官方文档:https://www.donet5.com/Home/Doc?typeId=1201 sqlsguar分表注意事项注意一:需要有一个分表字段,插入的时候...

K8s 通过 firewalld 放行端口

K8s通过firewalld放行端口对于etcd节点,运行以下命令: 1、firewall-cmd--permanent--add-port=2376/tcp 2、firewal...

vue3 ref的使用多个ref的使用。通过ref触发点击事件

多个ref获取的方法可以使用一样的,通过变量名来区分就行了 const vabUploadRef = ref() const multipleTableRef = ref() ...

vue切换菜单,vue菜单选中。跳转页面通过原生js设置选中样式。vue中使用原生js方法。js 找到当前对象的兄弟对象。js获取子节点。js获取父节点。js获取当前元素的同级节点

vue切换菜单,跳转页面通过原生js设置选中样式可以利用上面那个js获取当前元素的同级节点后先设置默认的样式,然后在设置点...

vue3 ref转化成 HTMLElement。vue3通过ref获取dom节点

vue3其实是可以直接利用ref获取dom节点的,代码如下&lt;template&gt; &lt;div class=&quot;app-container&quot;&gt; ...

docker 通过内部ip内网ip容器名,自定义网络别名,访问mysql。以及无法连接问题排查

docker 是可以通过内部ip,容器名,自定义网络别名,访问mysql的。一般来说只要mysql与程序在同一个网段都是可以使用内部ip...
a genius is the person who repeats the most times
排名
35
文章
15
粉丝
5
评论
5
vue.js 学习日记第五章-v-if和v-for指令的使用方式
饰心 : 吃惊!博客更新小王子?
vue.js 学习日记第三章-vue中的简单事件及事件修饰符
修心 : 一个专栏可以的!说一下前端的mvc就更好了
通过PlUpload控件配合WebApi接口完成压缩上传文件
剑轩 : 厉害了,这个很实用。这个可以实现图片压缩?
C#+selenium实现自动登录
剑轩 : 坐标不能是线性的,因为人拖动的时候不是线性的。可以试下这个思路...
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术
极霸矛,湘阿痕响啊。