.NET MVC中如何支持工程建筑行业的大文件夹上传与目录结构?

介绍

在Web 程序中上传文件是很常见的需求。利用HTTP 协议上传文件的方式非常有限,最常见的莫过于使用

元素进行上传。这种上传方式会将内容使用multipart/form-data 方案进行编码,并将内容POST 到服务器端。使用multipart/form-data 编码方式与默认的application/x-url-encoded 编码方式相比,在大数据量情况下效率要高很多。

使用

上传文件最大的优势在于编程方便,几乎各种服务器端技术都对这种上传方式做了良好的封装,使得程序员能够直观地对客户端上传的文件进行处理。不过总体来说,这个协议并不适合做文件传输,解析数据流内容的代价相对较高,并且没有一些例如断点续传的机制来辅助,导致在上传大文件时经常会力不从心。

有朋友认为使用

上传文件最大的问题在于内存占用太高,由于需要将整个文件载入内存进行处理,导致如果用户上传文件太大,或者同时上传的用户太多,会造成服务器端内存耗尽。这个观点其实是错误的。对于某些服务器端的技术,例如Spring Framework ,或者早期ASP.NET 1.1 时,为了供程序处理,都会将用户上传的内容完全载入内存,这的确会带来问题。但是其实协议本身并没有规定服务器端应该使用何种方式来处理上传的文件。例如在现在的ASP.NET 2.0 中就已经会在用户上传数据超过一定数量之后将其存在硬盘中的临时文件中,而这点对于开发人员完全透明,也就是说,开发人员可以像以前一样进行数据流的处理。

ASP.NET 2.0 启用硬盘临时文件的阈值(threshold )是可配置的:

maxRequestLength 自不必说,刚接触ASP.NET 的朋友总会发现上传文件不能超过4M ,这就是因为maxRequestLength 的大小默认为4096 ,这就限制着每个请求的大小不得超过4096KB 。这么做的目的是为了保护应用程序不受恶意请求的危害。当请求超过maxRequestLength 之后,ASP.NET 处理程序将不会处理该请求。这里和ASP.NET 抛出一个异常是不同的,这就是为什么如果用户上传文件太大,看到的并非是ASP.NET 应用程序中指定的错误页面(或者默认的),因为ASP.NET 还没有对这个请求进行处理。requestLengthDiskThreshold 就是刚才所提到的阈值,其默认值为256 ,即一个请求内容超过256KB 时就会启用硬盘作为缓存。这个阈值理论上和客户端是否是在上传内容无关,只要客户端发来的请求大于这个值即可。因此,在ASP.NET 2.0 中服务器的内存不会因为客户端的异常请求而耗尽。

如果我们需要在ASP.NET (如果没有特别说明,以下ASP.NET 均指ASP.NET 2.0 )应用中上传文件,我们一般就会直接使用

控件进行文件上传。如果一个页面中存在

控件,那么页面中form 元素的enctype 就会被自动改为multipart/form-data ,而且我们可以在页面PostBack 之后通过

控件的引用来获得客户端通过该控件所上传得文件。不过,如果上传文件的功能需要较为特别的需求—— 例如需要进度条提示,

控件就无能为力了。

确切地说,应该是

所能提供的支持非常有限,因此一些特殊需求我们不能实现—— 严格说来,应该是无法轻易地、直接地实现。这样,在实现这些功能时,我们就会绕一个大大的弯。为了避免每次实现相同功能时都要费神费时地走一遍弯路,因此出现了各种上传组件。上传组件提供了封装好的功能,使得我们在实现文件上传功能时变得轻松了很多。例如几乎所有的上传组件都直接或间接地提供了进度提示的功能,有的提供了当前的百分比数值,有的则直接提供了一套UI ;有的组件只提供了简单的UI ,有的却提供了一整套上传、删除的管理界面。此外,有的组件还提供了防止客户端恶意上传的能力。

关于ASP.NET 下的上传组件,最广为流传的方式莫过于在ASP.NET Pipeline 的BeginRequest 事件中截获当前的HttpWorkerRequest 对象,然后直接调用其ReadEntityBody 等方法获取客户端传递过来的数据流,并加以分析和处理。在ASP.NET 1.1 时期,这么做的目的是为了直接将数据写入硬盘,以避免上传内容消耗太多服务器内存,但是现在自然已经不会因为这个原因而这么做了。从客户端发起请求到一定规模的数据传输完毕需要一段时间,那么从HttpWorkerRequest 对象中读取数据流自然需要一段时间,而在这段时间内,客户端可以使用新的请求进行轮询来获得当前上传的状况。这就是获得上传进度的最传统的做法。这个做法的原理很容易理解,但是写出一个完整的组件其实很不容易,尤其是各种细节方面的问题会让人感到防不胜防。此类组件中最成功且最著名的莫过于NeatUpload 了。

NeatUpload 是一个开源组件,使用LGPL( Lesser General Public License) 许可协议,也就是说它是“business-friendly” 的。NeatUpload 可以在ASP.NET 和mono 中使用,能够将上传的文件存在硬盘中或者Sql Server 数据库中。NeatUpload 提供了两个服务器控件: 和 。前者用于代替 ,可以通过它访问到用户通过特定上传框上传的内容;后者则是一个进度条显示控件,负责使用弹出窗口或内联的形式显示上传的进度。弹出窗口自不必说,而所谓的“ 内联” 方式其实只是在页面中嵌入一个Iframe 元素,然后通过不断刷新iframe 中的页面来进行进度展示而已—— 可见它和弹出窗口显示方式的区别仅仅在页面所处的位置。当然,如果我们希望将其移植为AJAX 形式也不难,只需开发一个页面,继承NeatUpload 提供的ProgressPage 类,并通过ProgressPage 所提供的一些属性(总字节数,已上传字节数,已花时间,etc. )来获得当前上传的进度,最后直接使用Response.Write 输出JSON 形式的数据即可。事实上原本在iframe (或新窗口)中的页面,也是继承了ProgressPage 类,并且使用HTML 的方式进行呈现而已,本质上并没有太大区别。

不过个人认为,其实NeatUpload 的实用价值不高(这点稍后再述),它最大的意义还在于提供了一个完整的优秀的示例。NeatUpload 设计精巧,注释完整,是个不可多得学习案例。如果能够将NeatUpload 的代码研究一遍,那么相信在编程能力和ASP.NET 的理解上都会上一个新的台阶。此外,在NeatUpload 站点上还能够发现NeatHtml 。NeatHtml 是一个开源的Web 组件,用于显示不安全的内容(主要是用户输入内容,例如博客评论,论坛帖子等等),主要用于避免跨站脚本(XSS ,Cross-Site Scripting )等安全问题。作为组件的作者,Dean 还将NeatHtml 所用到的技术总结为一篇Whitepaper ,感兴趣的朋友可以看一下,这是一份不可多得的技术资料。

顺便提一下,个人认为目前很多开发人员的编程能力还不够,似乎很多人都过早地把精力放在了“ 设计” ,或者某个特定的技术上,而忽略了最基础的“ 编程能力” ,也就是将一段思路转化为代码实现的能力。我发现,很多朋友在解决问题的时候,似乎都能很快得到解决方案并且叙述出来,但是真正要使用代码来表现出来时却显得困难重重。其实在工作中,思路或解决方案可以通过讨论而获得,但是真正转化为代码的时候只能靠自己了。而且编程能力其实和所谓的“ 工作经验” 无关,我建议以“ 应届毕业生”“ 自居” 的朋友,可以定心地锻炼一下自己的编程能力。

与NeatUpload 类似的开源组件还有Memba Velodoc XP Edition ,它是Velodoc文件管理系统 的核心。不过严格说来,这不仅仅是一个上传组件,而是一套文件管理的解决方案,它包含:

  1. 一个兼容IIS 7 集成管道模式的ASP.NET Http Module ,支持大文件上传使用(有趣的是,NeatUpload 申明,IIS 7的一个 Bug 使它无法在IIS 7 集成管道模式中使用)。
  2. 一个支持断点续传的ASP.NET Http Handler 。
  3. 一系列ASP.NET 服务器端控件,提供了文件上传功能所需的UI ,包括一个多文件上传控件,一个ListView 控件和一个进度条控件。
  4. 一个Web 应用程序,可以替换FTP 的交换文件方式,支持Email 发送链接。它也是上面所提到的组件的使用示例。
  5. 一个Windows Service ,用于定期清理旧文件。
  6. 一个测试项目、一个部署项目、以及一个安装项目。
  7. 文档。
    回到NeatUpload 组件。说实话,我始终不喜欢这种进度获取方式,因为我觉得通过一个额外的请求对服务器进行轮询无疑是一个累赘。事实上,如果需要上传大文件并且获得上传进度,目前最好的方式应该是使用RIA 方式。最典型的RIA 上传方式就是利用Flash 了。ActionScript 2.0 中已经存在FileReference 和FileReferenceList 组件以支持单文件和多文件的上传,有了这两个组件,上传的各种信息已经能够完全在客户端获得,而上传进度也自然能够计算出来。FileReference 和FileReferenceList 组件非常容易使用,就连像我这样对Flash 一窍不通的人,也能在短时间内作出一个简单的上传功能。但是自从有了swfupload ,世界就变得更美好了。

严格说来,通过FileReference 所得到的上传进度是“ 客户端发送数据的进度” ,而像NeatUpload 的做法得到的是“ 服务器端接受数据的进度” ,两者不可混为一谈。

swfupload 也是个开源组件,顾名思义是使用Flash 进行上传。不过对于swfupload 来说,Flash 的作用主要是“ 控制” ,而不是“ 展示” ,这无疑给了开发人员更大的灵活性。swfupload 的实现方式自然是利用了FileReference 和FileReferenceList 组件所提供的功能,通过Flash 与JavaScript 的交互能力,使得开发文件上传功能变得非常优雅和容易。有了swfupload ,开发人员可以使用JavaScript 来实现各种显示方式,开发像Flicker 一样酷酷的上传界面也不再是非常困难的事情了。

swfupload 是个客户端组件,它对于服务器端来说完全透明,也就是说,服务器端只需要使用对待普通form 的方式来处理即可。例如在ASP.NET 中我们可以使用Generic Handler 来处理客户端的文件上传。如下,fileCollection 变量即为客户端Post 至服务器端所有文件的集合,我们可以使用name 或下标的方式来获得其中的HttpPostedFile 对象。:

publicclassUploadHandler:IHttpHandler{publicvoidProcessRequest(HttpContextcontext){HttpFileCollectionfileColllection=context.Request.Files;...}publicboolIsReusable{...}}

既然Flash 提供了文件上传功能,Silverlight 作为微软主推的RIA 技术也不会缺了这项功能。这篇文章 源自Silverlight 2.0 的Quick Starts ,展示了如何使用Silverlight 2.0 开发文件上传的功能,感兴趣的朋友可以一读。

围绕着ASP.NET 中上传文件这个话题也讨论了不少了,还有什么没有涉及到的吗?个人认为其实至少还有一个非常重要问题是没有讨论过,那就是在处理上传文件时占用ASP.NET 处理线程的问题。众所周知,ASP.NET 处理请求时会用到线程池中的线程,当线程池中的线程被用完之后没有被处理的请求只能排队了。因此增大ASP.NET 应用程序吞吐量的一个重要手段,就是为一些耗时的操作使用异步处理方式(事实上这一命题可以在大部分应用中成立)。例如一个数据库查询操作需要3 秒钟,如果不使用异步操作,处理线程就会被阻塞,直至查询完成。如果使用异步方式来执行数据库查询,在这3 秒钟内线程就可以用户处理其他请求,当异步操作结束之后,ASP.NET 就会使用另一个线程来继续处理这个请求。

上传大文件也是一个长时间占用处理线程的工作,而且遗憾的是,这无法使用异步操作来完成(通过异步操作来释放处理线程需要操作系统的支持,因此只有少量功能可以使用异步操作)。如果一个文件上传需要3 分钟时间,那么在这3 分钟内就会独占一个处理线程,如果上传文件的连接一多,就会大大影响应用程序的性能—— 就像遭受了某种方式的DOS 攻击一样。因此,即使使用了像NeatUpload 和swfupload 这样的组件,也无法解决上传连接过多造成可用线程减少的问题。要解决这个问题并不容易,以下是两种思路(欢迎大家就此问题进行讨论):

扩展IIS ,使上传文件或处理文件的过程不经ASP.NET 处理,以减少ASP.NET 应用程序线程的消耗。现在有了IIS 7 ,如果使用集成管道模式,应该也可以使用托管代码进行扩展。
使用额外的ASP.NET 应用程序处理文件上传,以节省上传文件的线程对原ASP.NET 应用程序线程的消耗。
就先说到这里吧。

下载完整示例

下载完整示例

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1159059.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

导师推荐!专科生必备!8款AI论文平台测评TOP8

导师推荐!专科生必备!8款AI论文平台测评TOP8 2026年专科生论文写作工具测评:选对平台,事半功倍 随着AI技术在学术领域的广泛应用,越来越多的专科生开始借助AI论文平台提升写作效率与质量。然而,面对市场上琳…

强烈安利9个一键生成论文工具,本科生搞定毕业论文不求人!

强烈安利9个一键生成论文工具,本科生搞定毕业论文不求人! AI 工具如何让论文写作变得轻松高效 在当今信息爆炸的时代,本科生撰写毕业论文早已不再是单纯的文字创作,而是一场对效率、逻辑和学术规范的全面挑战。面对繁重的文献查阅…

C#代码示例:如何在网页上实现机械制造行业的大文件秒传?

文件管理系统毕业设计:从IE8兼容到百万梦想的奇幻漂流 大家好,我就是那个被IE8折磨到怀疑人生的通讯专业大三狗。本来以为做个文件管理系统毕业设计撑死两周搞定,没想到这项目直接让我体验了一把"全栈工程师"的酸爽人生。 需求分…

中小企业福音,快速部署的PHP进销存系统,一步迈入高效管理

温馨提示:文末有资源获取方式对于众多中小企业而言,引入一套管理系统的最大顾虑往往是:部署是否复杂?员工是否能用得起来?成本是否高昂?现在,所有顾虑都可以放下。我们推出一款真正为中小企业量…

C++构造函数中慎用虚函数

1.C构造函数中慎用虚函数你遇到的这个警告来自 Clang Static Analyzer(clang-analyzer),具体是:Call to virtual method ModParam::setJsonData during construction bypasses virtual dispatch [clang-analyzer-optin.cplusplus.…

AI编辑器trae的solo模式是什么?

Trae 的 SOLO 模式是字节跳动 AI 编程 IDE Trae 中以 AI 为主导的全流程自动化开发模式,核心是让 AI 自主完成从需求理解、任务拆解、编码、测试到部署的完整开发链路,开发者仅需以自然语言输入需求并可随时介入调整,无需手动操作全流程Trae。…

如何在.NET WebForm中实现能源化工行业的大文件分片断点续传?

大文件传输系统技术方案 作为江苏某软件公司的技术负责人,在处理公司产品部门提出的大文件传输需求时,我经过详细调研和评估,提出以下技术方案: 需求分析与技术挑战 当前需求面临的主要技术挑战包括: 超大文件传输…

融媒体中心三审三校的必要性,为什么?

“三审三校”制度不仅是传统出版业的优良传统,更是融媒体中心生存与发展的“生命线”和“安全阀”。在“一次采集、多种生成、多元传播”的融媒体环境下,实行严格的“三审三校”具有以下四大核心必要性:一、 守住政治安全的“底线”&#xff…

JDK17 前后写法对比:差点没认出是 Java

Java,一直被开发者戏称为“啰嗦”,但从 JDK 12 到 JDK 17,这门语言发生了显著变化。多个语法层面的增强让 Java 更加简洁、表达力更强,也更接近现代语言的风格。本文将带你梳理这六个版本中 Java 的关键语法演进。👀语…

ROS2开发

ROS 2(Robot Operating System 2)是用于机器人开发的灵活框架,相较于 ROS 1,它在实时性、安全性、跨平台支持和分布式通信等方面有显著提升。以下是一个 ROS 2 开发的快速入门指南,适用于初学者或希望系统化学习的人。…

信创环境下XHEDITOR怎样处理Word公式粘贴兼容性问题?

作为一名山西PHP程序员的外包奇遇记 大家好!我是来自山西的一名PHP程序员,最近刚接了个CMS企业官网的外包项目,客户突然甩来个"豪华套餐"需求——要在后台编辑器里加一堆高大上的文档导入功能。 客户需求大揭秘 客户要求&#x…

解读GB/T4857.23-2021 医疗器械运输包装振动测试意义

在医疗器械、生物制药、疫苗等行业,产品运输过程中的安全性与稳定性直接关系到临床使用效果和患者生命安全。GB/T4857.23-2021《包装 运输包装件基本试验 第23部分:垂直随机振动试验方法》作为运输包装振动测试的重要标准,为相关企业提供了科…

教室照明如何影响学生视力健康与学习效率?

伴着教育环境持续改进,教室照明身为学生日常学习里重要的物理条件,其质量径直对学生的视力健康及学习效率产生影响。根据近些年多项调查数据所示,我国青少年近视率始终处于高位,部分年龄段近视占比已逾35%。此种现象除和用眼习惯、…

金融风控平台怎样将Excel公式转存为XHEDITOR可编辑格式?

山西PHP程序员的逆袭之路:用代码搞钱,用QQ群发家! 各位老铁们好!我是老张,一个在山西太原窝着写PHP的"码农"。最近接了个CMS企业官网的外包项目,客户提出了个"变态"需求:要…

XHEDITOR前端如何兼容Word公式跨浏览器粘贴?

山西PHP程序员的逆袭之路:用代码搞钱,用QQ群发家! 各位老铁们好!我是老张,一个在山西太原窝着写PHP的"码农"。最近接了个CMS企业官网的外包项目,客户提出了个"变态"需求:要…

军工系统如何通过XHEDITOR实现Word公式安全导入?

山西PHP程序员的Word粘贴大冒险 大家好,我是山西的一个苦逼PHP程序员,最近接了个CMS企业官网的外包项目。客户突然甩给我一个需求,让我在xhEditor编辑器里加个能直接粘贴Word的功能,还要支持各种文档导入和公式转换… 需求分析 …

【VTK手册041】切片抽取工具:vtkCutter原理解析

【VTK手册041】切片抽取工具:vtkCutter原理解析 在医学图像处理与三维可视化领域,切片抽取(Slicing)是分析解剖结构最常用的手段之一。VTK 提供的 vtkCutter 是实现这一核心功能的基石类。本文将深入解析 vtkCutter 的基本原理、核…

【VTK 手册040】vtkPlane 详解:原理、用法与源码剖析

【VTK 手册040】vtkPlane 详解:原理、用法与源码剖析 1. 概述 在医学图像处理中,平面的定义与计算无处不在。无论是 MPR(多平面重建)、图像裁剪(Clipping) 还是 解剖结构对齐,都离不开平面模型。…

手把手拆解旅行搭子Pro:基于Astron的Agent工作流实战

文章目录1. 前言:为什么需要 Agent 工作流?2. 提示词Agent与工作流Agent2.1 提示词驱动的智能体2.2 工作流驱动智能体3. 旅行搭子Agent工作流设计理念3.1 工作流规则3.2 工作流结构设计4. 星辰 Agent 平台工作流实战(旅行搭子)4.1…

亲测好用!10款AI论文平台测评:研究生开题报告神器

亲测好用!10款AI论文平台测评:研究生开题报告神器 2026年AI论文平台测评:为何值得一看 在当前学术研究日益数字化的背景下,AI论文平台已成为研究生群体不可或缺的辅助工具。然而,面对市场上众多功能相似的产品&#xf…