zoukankan      html  css  js  c++  java
  • ueditor 文件上传的分析和总结

    正式开始之前,先写两个常用又容易被我忘掉的文件和流相互转化的方法。

    1,文件转流

    FileStream fs = new FileStream(filename,FileMode.Open,FileAccess.Read);
    byte[] infbytes = new byte[(int)fs.Length];
    fs.Read(infbytes, 0, infbytes.Length);
    fs.Close();
    return infbytes;

    2,流转文件

    FileStream fs = new FileStream("D:inf.dlv",FileMode.Create,FileAccess.Write);
    fs.Write(infbytes, 0, inf.Length);
    fs.Close();

           目前来说,自己这边网站有两个上传文件(尤其是图片)的方式,一个是通过aspx的文件上传控件直接在pageload里面接受和操作。一个是jquery上传的控件或者用<input type="file">直接上传,我觉得第二中比较具有普遍性,所以最先讨论第二种。

           需求:1,接收用户上传的图片。  2,对图片格式和大小有要求。  3,图片需要压缩 。  4,压缩后的图片需要 裁剪,打水印。 5,存到以用户名为名的文件夹下的三个不同的文件夹。 6,以时间戳和随机数命名文件以防止重名。7,接收之后返回新的文件在服务器的相对路径。

    第一步:前台页面的代码

    有一点需要特别注意,在提交文件的表单中,action="uploadHandler.ashx"这个属性是不能缺少的,是设置表单的MIME编码。默认情况,这个编码格式是application/x-www-form-urlencoded,不能用于文件上传;只有使用了multipart/form-data,才能完整的传递文件数据,进行接下来的操作。(MIME是一种保证非ASCII码文件在internet上传播的规格)

    <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 runat="server" id="form1" method="post" enctype="multipart/form-data" action="uploadHandler.ashx">
    
            <input name="file" type="file" id="upLoad" />
            <input name="action" type="hidden" value="uploadImage" />
            <input name="s" type="submit" />
        </form>
    </body>
    </html>

    隐藏域是用来设置提交方式的,模拟多种提交,比如文件提交,图片提交,批量提交。

    第二部,控制器,这里只写了一种配置,就是上传图片的配置

       public void ProcessRequest(HttpContext context)
            {
                
                Handler action = null;
                switch (context.Request["action"])
                {
                    case "uploadimage":
                        action = new UploadHandler(context, new UploadConfig()//从配置文件中读取配置
                            {
                                AllowExtensions = Config.GetStringList("imageAllowFiles"),
                                PathFormat = Config.GetString("imagePathFormat"),
                                SizeLimit = Config.GetInt("imageMaxSize"),
                                UploadFieldName = Config.GetString("imageFieldName"),
                            });
                        break;
                    default:
                        break;
                }
                action.Process();
            }

    然后是处理类的基类,是一个抽象类,关于抽象类,虚方法,还有比如base调用父类的构造函数这些都属于C#面向对象多态的内容,这个需要重新写一篇东西来总结。

    public abstract class Handler
        {
    
            public Handler(HttpContext context)
            {
                this.Request = context.Request;
                this.Response = context.Response;
                this.Context = context;
                this.Server = context.Server;
                this.Cookies = context.Request.Cookies;
            }
            /// <summary>
            /// 抽象出来的处理程序,必须被子类重写才能使用
            /// </summary>
            public abstract void Process();
            /// <summary>
            /// 给前台返回结果用的方法,
            /// </summary>
            /// <param name="response"></param>
            protected void WriteJson(object response)
            {
                string jsonpCallback = Request["callback"],
                    json = JsonConvert.SerializeObject(response);
                if (String.IsNullOrWhiteSpace(jsonpCallback))
                {
                    Response.AddHeader("Content-Type", "text/plain");
                    Response.Write(json);
                }
                else
                {
                    Response.AddHeader("Content-Type", "application/javascript");
                    Response.Write(String.Format("{0}({1});", jsonpCallback, json));
                }
                Response.End();
            }
            public HttpRequest Request { get; private set; }
            public HttpResponse Response { get; private set; }
            public HttpContext Context { get; private set; }
            public HttpServerUtility Server { get; private set; }
            public HttpCookieCollection Cookies { get; set; }
    
    
        }

    这个是真正的处理类uploadHandler

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using Newtonsoft.Json;
    using System.IO;
    namespace imageTest
    {
        public class UploadHandler : Handler
        {
            //把两个存储类当做本类的属性
            public UploadConfig UploadConfig { get; private set; }
            public UploadResult Result { get; private set; }
            /// <summary>
            /// 在派生类中访问基类的构造函数
            /// </summary>
            /// <param name="context"></param>
            /// <param name="config"></param>
            public UploadHandler(HttpContext context, UploadConfig config)
                : base(context)
            {
                this.UploadConfig = config;
                this.Result = new UploadResult() { State = UploadState.Unknown };
            }
            /// <summary>
            /// 正式的重写这个处理程序
            /// </summary>
            public override void Process()
            {
                byte[] uploadFileBytes = null;
                string uploadFileName = null;
                HttpPostedFile file = Request.Files[UploadConfig.UploadFieldName];
                uploadFileName = file.FileName;
                if (!CheckFileType(uploadFileName))
                {
                    Result.State = UploadState.TypeNotAllow;
                    WriteResult();
                    return;
                }
                if (!CheckFileSize(file.ContentLength))
                {
                    Result.State = UploadState.SizeLimitExceed;
                    WriteResult();
                    return;
                }
             //在所有的判断都结束之后,正式的对文件进行处理,这个没写
    
    
    
            }
            private void WriteResult()
            {
                this.WriteJson(new
                {
                    state = GetStateMessage(Result.State),
                    url = Result.Url,
                    title = Result.OriginFileName,
                    original = Result.OriginFileName,
                    error = Result.ErrorMessage
                });
            }
    
            private string GetStateMessage(UploadState state)
            {
                switch (state)
                {
                    case UploadState.Success:
                        return "SUCCESS";
                    case UploadState.FileAccessError:
                        return "文件访问出错,请检查写入权限";
                    case UploadState.SizeLimitExceed:
                        return "文件大小超出服务器限制";
                    case UploadState.TypeNotAllow:
                        return "不允许的文件格式";
                    case UploadState.NetworkError:
                        return "网络错误";
                }
                return "未知错误";
            }
    
    
    
            private bool CheckFileSize(int size)
            {
                return size < UploadConfig.SizeLimit;
            }
            private bool CheckFileType(string filename)
            {
                var fileExtension = Path.GetExtension(filename).ToLower();
                return UploadConfig.AllowExtensions.Select(x => x.ToLower()).Contains(fileExtension);
            }
        }
        /// <summary>
        /// 上传配置对象,主要是用来读取后存放配置数据
        /// </summary>
        public class UploadConfig
        {
            /// <summary>
            /// 文件命名规则
            /// </summary>
            public string PathFormat { get; set; }
    
            /// <summary>
            /// 上传表单域名称
            /// </summary>
            public string UploadFieldName { get; set; }
    
            /// <summary>
            /// 上传大小限制
            /// </summary>
            public int SizeLimit { get; set; }
    
            /// <summary>
            /// 上传允许的文件格式
            /// </summary>
            public string[] AllowExtensions { get; set; }
    
            /// <summary>
            /// 文件是否以 Base64 的形式上传
            /// </summary>
            public bool Base64 { get; set; }
    
            /// <summary>
            /// Base64 字符串所表示的文件名
            /// </summary>
            public string Base64Filename { get; set; }
    
            /// <summary>
            /// 用户的用户名
            /// </summary>
            public string UserName { get; set; }
    
    
            public string WaterUrl { get;set;}
            public string SmallUrl { get; set; }
            public string 
        }
        /// <summary>
        /// 上传结果对象,主要是用来存储程序的处理结果
        /// </summary>
        public class UploadResult
        {
            public UploadState State { get; set; }
            public string Url { get; set; }
            public string OriginFileName { get; set; }
    
            public string ErrorMessage { get; set; }
        }
        /// <summary>
        /// 枚举类型,程序的处理结果.
        /// </summary>
        /// 
        public enum UploadState
        {
            Success = 0,
            SizeLimitExceed = -1,
            TypeNotAllow = -2,
            FileAccessError = -3,
            NetworkError = -4,
            Unknown = 1,
        }
    }

    总结一下人家的设计思路,editor最先通过自己的js的配置文件初始化编辑器并且找到路径来访问control.ashx一般处理程序,ashx通过http访问的表单的action来判断是哪种操作,是上传文件还是图片还是读取等等,然后通过这个action,去config.json里面来读取具体的关于文件上传和下载等等配置,把这些配置通过配置对象加上httpcontext上下文一起传到文件上传控制类uploadHandler,uploadHandler继承自handler,所以构造函数可以调用基类的,process方法也是重写基类的抽象方法。

            

  • 相关阅读:
    jq---方法总结
    Coderfroces 862 B . Mahmoud and Ehab and the bipartiteness
    Coin
    joisino's travel
    日天的终生大事(dp)
    Codefroces 852 G. Bathroom terminal
    Codefroces432 div2 A,B,C
    Atcoder ABC 069 C
    Codefroces 849 A,B
    HDU 6186 CS Course
  • 原文地址:https://www.cnblogs.com/codersun/p/4884571.html
Copyright © 2011-2022 走看看