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

1,文件转流

  1. FileStream fs = new FileStream(filename,FileMode.Open,FileAccess.Read);
  2. byte[] infbytes = new byte[(int)fs.Length];
  3. fs.Read(infbytes, , infbytes.Length);
  4. fs.Close();
  5. return infbytes;

2,流转文件

  1. FileStream fs = new FileStream("D:\inf.dlv",FileMode.Create,FileAccess.Write);
  2. fs.Write(infbytes, , inf.Length);
  3. 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上传播的规格)

  1. <html xmlns="http://www.w3.org/1999/xhtml">
  2. <head runat="server">
  3. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  4. <title></title>
  5. </head>
  6. <body>
  7. <form runat="server" id="form1" method="post" enctype="multipart/form-data" action="uploadHandler.ashx">
  8.  
  9. <input name="file" type="file" id="upLoad" />
  10. <input name="action" type="hidden" value="uploadImage" />
  11. <input name="s" type="submit" />
  12. </form>
  13. </body>
  14. </html>

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

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

  1. public void ProcessRequest(HttpContext context)
  2. {
  3.  
  4. Handler action = null;
  5. switch (context.Request["action"])
  6. {
  7. case "uploadimage":
  8. action = new UploadHandler(context, new UploadConfig()//从配置文件中读取配置
  9. {
  10. AllowExtensions = Config.GetStringList("imageAllowFiles"),
  11. PathFormat = Config.GetString("imagePathFormat"),
  12. SizeLimit = Config.GetInt("imageMaxSize"),
  13. UploadFieldName = Config.GetString("imageFieldName"),
  14. });
  15. break;
  16. default:
  17. break;
  18. }
  19. action.Process();
  20. }

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

  1. public abstract class Handler
  2. {
  3.  
  4. public Handler(HttpContext context)
  5. {
  6. this.Request = context.Request;
  7. this.Response = context.Response;
  8. this.Context = context;
  9. this.Server = context.Server;
  10. this.Cookies = context.Request.Cookies;
  11. }
  12. /// <summary>
  13. /// 抽象出来的处理程序,必须被子类重写才能使用
  14. /// </summary>
  15. public abstract void Process();
  16. /// <summary>
  17. /// 给前台返回结果用的方法,
  18. /// </summary>
  19. /// <param name="response"></param>
  20. protected void WriteJson(object response)
  21. {
  22. string jsonpCallback = Request["callback"],
  23. json = JsonConvert.SerializeObject(response);
  24. if (String.IsNullOrWhiteSpace(jsonpCallback))
  25. {
  26. Response.AddHeader("Content-Type", "text/plain");
  27. Response.Write(json);
  28. }
  29. else
  30. {
  31. Response.AddHeader("Content-Type", "application/javascript");
  32. Response.Write(String.Format("{0}({1});", jsonpCallback, json));
  33. }
  34. Response.End();
  35. }
  36. public HttpRequest Request { get; private set; }
  37. public HttpResponse Response { get; private set; }
  38. public HttpContext Context { get; private set; }
  39. public HttpServerUtility Server { get; private set; }
  40. public HttpCookieCollection Cookies { get; set; }
  41.  
  42. }

这个是真正的处理类uploadHandler

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using Newtonsoft.Json;
  6. using System.IO;
  7. namespace imageTest
  8. {
  9. public class UploadHandler : Handler
  10. {
  11. //把两个存储类当做本类的属性
  12. public UploadConfig UploadConfig { get; private set; }
  13. public UploadResult Result { get; private set; }
  14. /// <summary>
  15. /// 在派生类中访问基类的构造函数
  16. /// </summary>
  17. /// <param name="context"></param>
  18. /// <param name="config"></param>
  19. public UploadHandler(HttpContext context, UploadConfig config)
  20. : base(context)
  21. {
  22. this.UploadConfig = config;
  23. this.Result = new UploadResult() { State = UploadState.Unknown };
  24. }
  25. /// <summary>
  26. /// 正式的重写这个处理程序
  27. /// </summary>
  28. public override void Process()
  29. {
  30. byte[] uploadFileBytes = null;
  31. string uploadFileName = null;
  32. HttpPostedFile file = Request.Files[UploadConfig.UploadFieldName];
  33. uploadFileName = file.FileName;
  34. if (!CheckFileType(uploadFileName))
  35. {
  36. Result.State = UploadState.TypeNotAllow;
  37. WriteResult();
  38. return;
  39. }
  40. if (!CheckFileSize(file.ContentLength))
  41. {
  42. Result.State = UploadState.SizeLimitExceed;
  43. WriteResult();
  44. return;
  45. }
  46. //在所有的判断都结束之后,正式的对文件进行处理,这个没写
  47.  
  48. }
  49. private void WriteResult()
  50. {
  51. this.WriteJson(new
  52. {
  53. state = GetStateMessage(Result.State),
  54. url = Result.Url,
  55. title = Result.OriginFileName,
  56. original = Result.OriginFileName,
  57. error = Result.ErrorMessage
  58. });
  59. }
  60.  
  61. private string GetStateMessage(UploadState state)
  62. {
  63. switch (state)
  64. {
  65. case UploadState.Success:
  66. return "SUCCESS";
  67. case UploadState.FileAccessError:
  68. return "文件访问出错,请检查写入权限";
  69. case UploadState.SizeLimitExceed:
  70. return "文件大小超出服务器限制";
  71. case UploadState.TypeNotAllow:
  72. return "不允许的文件格式";
  73. case UploadState.NetworkError:
  74. return "网络错误";
  75. }
  76. return "未知错误";
  77. }
  78.  
  79. private bool CheckFileSize(int size)
  80. {
  81. return size < UploadConfig.SizeLimit;
  82. }
  83. private bool CheckFileType(string filename)
  84. {
  85. var fileExtension = Path.GetExtension(filename).ToLower();
  86. return UploadConfig.AllowExtensions.Select(x => x.ToLower()).Contains(fileExtension);
  87. }
  88. }
  89. /// <summary>
  90. /// 上传配置对象,主要是用来读取后存放配置数据
  91. /// </summary>
  92. public class UploadConfig
  93. {
  94. /// <summary>
  95. /// 文件命名规则
  96. /// </summary>
  97. public string PathFormat { get; set; }
  98.  
  99. /// <summary>
  100. /// 上传表单域名称
  101. /// </summary>
  102. public string UploadFieldName { get; set; }
  103.  
  104. /// <summary>
  105. /// 上传大小限制
  106. /// </summary>
  107. public int SizeLimit { get; set; }
  108.  
  109. /// <summary>
  110. /// 上传允许的文件格式
  111. /// </summary>
  112. public string[] AllowExtensions { get; set; }
  113.  
  114. /// <summary>
  115. /// 文件是否以 Base64 的形式上传
  116. /// </summary>
  117. public bool Base64 { get; set; }
  118.  
  119. /// <summary>
  120. /// Base64 字符串所表示的文件名
  121. /// </summary>
  122. public string Base64Filename { get; set; }
  123.  
  124. /// <summary>
  125. /// 用户的用户名
  126. /// </summary>
  127. public string UserName { get; set; }
  128.  
  129. public string WaterUrl { get;set;}
  130. public string SmallUrl { get; set; }
  131. public string
  132. }
  133. /// <summary>
  134. /// 上传结果对象,主要是用来存储程序的处理结果
  135. /// </summary>
  136. public class UploadResult
  137. {
  138. public UploadState State { get; set; }
  139. public string Url { get; set; }
  140. public string OriginFileName { get; set; }
  141.  
  142. public string ErrorMessage { get; set; }
  143. }
  144. /// <summary>
  145. /// 枚举类型,程序的处理结果.
  146. /// </summary>
  147. ///
  148. public enum UploadState
  149. {
  150. Success = ,
  151. SizeLimitExceed = -,
  152. TypeNotAllow = -,
  153. FileAccessError = -,
  154. NetworkError = -,
  155. Unknown = ,
  156. }
  157. }

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

ueditor 文件上传的分析和总结的更多相关文章

  1. Java Web文件上传原理分析(不借助开源fileupload上传jar包)

    Java Web文件上传原理分析(不借助开源fileupload上传jar包) 博客分类: Java Web   最近在面试IBM时,面试官突然问到:如果让你自己实现一个文件上传,你的代码要如何写,不 ...

  2. 1.5 webshell文件上传漏洞分析溯源(1~4)

    webshell文件上传漏洞分析溯源(第一题) 我们先来看基础页面: 先上传1.php ---->   ,好吧意料之中 上传1.png  ---->   我们查看页面元素 -----> ...

  3. UEditor编辑器两个版本任意文件上传漏洞分析

    0x01 前言 UEditor是由百度WEB前端研发部开发的所见即所得的开源富文本编辑器,具有轻量.可定制.用户体验优秀等特点 ,被广大WEB应用程序所使用:本次爆出的高危漏洞属于.NET版本,其它的 ...

  4. [转]UEditor编辑器两个版本任意文件上传漏洞分析

    0x01 前言 UEditor是由百度WEB前端研发部开发的所见即所得的开源富文本编辑器,具有轻量.可定制.用户体验优秀等特点 ,被广大WEB应用程序所使用:本次爆出的高危漏洞属于.NET版本,其它的 ...

  5. 【代码审计】UKCMS_v1.1.0 文件上传漏洞分析

      0x00 环境准备 ukcms官网:https://www.ukcms.com/ 程序源码下载:http://down.ukcms.com/down.php?v=1.1.0 测试网站首页: 0x0 ...

  6. 【代码审计】XYHCMS V3.5文件上传漏洞分析

      0x00 环境准备 XYHCMS官网:http://www.xyhcms.com/ 网站源码版本:XYHCMS V3.5(2017-12-04 更新) 程序源码下载:http://www.xyhc ...

  7. 【代码审计】JTBC(CMS)_PHP_v3.0 任意文件上传漏洞分析

      0x00 环境准备 JTBC(CMS)官网:http://www.jtbc.cn 网站源码版本:JTBC_CMS_PHP(3.0) 企业版 程序源码下载:http://download.jtbc. ...

  8. 【代码审计】QYKCMS_v4.3.2 任意文件上传漏洞分析

      0x00 环境准备 QYKCMS官网:http://www.qykcms.com/ 网站源码版本:QYKCMS_v4.3.2(企业站主题) 程序源码下载:http://bbs.qingyunke. ...

  9. 【代码审计】BootCMS v1.1.3 文件上传漏洞分析

      0x00 环境准备 BootCMS官网:http://www.kilofox.net 网站源码版本:BootCMS v1.1.3  发布日期:2016年10月17日 程序源码下载:http://w ...

随机推荐

  1. Parallel.For 你可能忽视的一个非常实用的重载方法

    说起Parallel.For大家都不会陌生,很简单,不就是一个提供并行功能的for循环吗? 或许大家平时使用到的差不多就是其中最简单的那个重载方法,而真实情况 下Parallel.For里面有14个重 ...

  2. 【iOS】7.4 定位服务->2.1.3.3 定位 - 官方框架CoreLocation 功能3:区域监听

    本文并非最终版本,如果想要关注更新或更正的内容请关注文集,联系方式详见文末,如有疏忽和遗漏,欢迎指正. 本文相关目录: ================== 所属文集:[iOS]07 设备工具 === ...

  3. python学习之路-书籍推荐

    学python有一段时间了,总结走来的路,发现还是看书靠谱,当然也要多实践. 一.入门篇 1.简明 Python 教程(A Byte of python) http://www.kuqin.com/a ...

  4. ThinkPHP3.2.3版本验证码异步第二次验证时失败的问题解决

    最近在用TP3.2.3做一个小项目,纠结于验证码验证问题,重点在于二次验证,举个例子就是常见的登录页面上有个验证码输入框,当用户输入验证码并且鼠标点击在这个输入框之外时候,触发onblur事件,然后a ...

  5. 获取JVM的dump文件

    获取JVM的dump文件的两种方式 1. JVM启动时增加两个参数: #出现 OOME 时生成堆 dump: -XX:+HeapDumpOnOutOfMemoryError #生成堆文件地址: -XX ...

  6. Java排序算法之直接选择排序

    Java排序算法之直接选择排序 基本过程:假设一序列为R[0]~R[n-1],第一次用R[0]和R[1]~R[n-1]相比较,若小于R[0],则交换至R[0]位置上.第二次从R[1]~R[n-1]中选 ...

  7. 实践 config drive - 每天5分钟玩转 OpenStack(170)

    如果 instance 无法通过 metadata service 获取 metadata(无 DHCP 或者 nova-api-metadata 服务),instance 还可以通过 config ...

  8. Web前端面试指导(十四):如何居中一个元素(正常、绝对定位、浮动元素)?

    题目点评 这道题目的提问比较多,连续问了三个问题,正常元素.绝对定位元素.互动元素如何居中,而且居中没有说清楚是垂直居中还是水平居中,要回答清楚这个问题,必须得有深厚的功底,而且要分类的来回答,条理要 ...

  9. 浅谈C10K问题

    在大型的APP中进行高并发的访问,淘宝,支付宝,微信,QQ,等 C10K问题:高并发的进行访问 C10K问题的最大特点是:设计不够良好的程序,其性能和连接数及机器性能的关系往往 是非线性的.举个例子: ...

  10. Realm数据持久化方案的简单介绍和使用(二)

    接上篇... 4. 可空属性&默认值&忽略属性 默认情况下, 属性值可空, 如果强制要求某个属性非空, 可以使用如下方法: 遵循协议方法 + (NSArray *)requiredPr ...