MVC&WebForm对照学习:文件上传(以图片为例)
博客园::首页:: :: :: ::管理 |
|
在web应用中,文件上传是个很普遍的功能,那么今天就来小结一下asp.net中文件上传的方式。首先我们快速来回忆一下WebForm中的文件上传的方法。 Part 1 WebForm中的文件上传
aspx: <div> aspx.cs: protected void btnSubmit_ServerClick(object sender, EventArgs e) 运行结果: Note:如果image是普通的html服务器控件,那么后台赋值就要这样: img1.Src = "~/uploads/" + filePath;
aspx: <div> aspx.cs: if (fileimg.PostedFile.ContentLength > 0) 运行也能实现同样的效果。
aspx: <div> aspx.cs if (Request.Files["fileimage"].HasFile()) Note:以上仅仅为了说明问题,故省去了对文件size的判断。 回过头来在看看,我们会发现如下关系: --------------------------------------------------------------------------------------------- 再来看看它们最终save的方法: ---------------------------html服务器控件------------------------------------------ ---------------------------html标签------------------------------------------------ Note:由于服务器控件FileUpload,我暂时还没办法通过反序列化查看到内部细节,故缺少图片。 通过上面三种不同的标签的实现方式,可以看出基本上都是殊途同归。因为我们知道服务器控件只是封装了某些东西,(虽然通过反编译有些代码还是查看不到)我们完全可以揣测,这种实现其实就是最终第三种方式来实现的,使我们操作起来更加方便而已,它最终还是要转换成普通的html标签。因此服务器控件的性能相比较而言有所损失。但是由于它会根据不同的浏览器生成一些样式和脚本,因此兼容性会较好。那么抛开兼容性不说,既然它们最终的实现方式是一样的(HttpPostedFile对象),那么我们完全可以抽象出一个共通的方法来实现,以省去每次使用它们的时候要写不同的处理方式。一下以html控件为例:
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- public static void Upload(string filePath) -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- private static void CreateFolderIfNeeded(string path) { --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- public static class HttpPostFileExtensions { //扩展方法必须在顶级类中定义 注1:特别注意的是由于Request.Files是名称值对的集合,而名称正是html标签的name属性的值,故使用普通的html控件的时候需要给file标签加上name属性,否则后台无法获取到它的值。 Part 2 MVC中的文件上传 如果习惯了使用WebForm服务器控件开发,那么初次接触MVC(本文以razor为例),你会发现这些服务器控件已经派不上用场了,就以文件上传为例,我们没办法像以前那样使用FileUpload愉快地拖曳来实现文件上传了。当然了所有的ASP.NET服务器控件也好,html服务器控件也好包括MVC的Htmlhelper,这些最终都要生成普通的html标签。而且MVC和WebForm都是基于ASP.NET平台的,那么从这2个点来说,我们在上文中最后提供的一个抽象封装(当然这只是一个简单的demo,它不能满足所有的实际开发中的变化了的需求)方法按道理来说也适用于MVC,那么究竟是不是这样呢?小段代码为证: @using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "form1", enctype = "multipart/form-data" })) ---------------------------------------------------------------------请允许我丑陋的展现方式------------------------------------------------------------------------------------- [HttpPost] ---------------------------------------------------------------------运行结果--------------------------------------------------------------------------------------------------- Note:以上使用了UpLoadFileHelper.Upload只是为了说明问题。实际开发中随着页面需求的变化,这个实现也要进行重构,也恳请博友能够提供完美的方案。 在WebForm中有HttpPostedFile对象,同样的在MVC中也有HttpPostedFileBase(我不知道微软是不是有意在名字上加以区分)。其实它们反应到上下文中是一样的。像这样的情况还有很多,比方说细心的你一定会发现,在Controller中取到的HttpContext是HttpContextBase而在WebForm中是HttpContext。虽然他们是两个不同的对象,但是内部实现是一样的(当然我没有查阅所有的这些类似的对象,也不保证所有的这些类似对象都是同样的实现)。那么我们就使用HttpPostedFileBase来看看MVC中如何实现单个文件的上传的: [HttpPost] 同样也能实现同样的效果。 Note:由于HttpPostedFileBase是从Request.Files["name"]得到的,因此Action中HttpPostedFileBase的变量名必须保持和View中file标签的name属性值一致。 Part 3 问题开发 众所周知,file input标签在不同的浏览器中会展现不同的样式,在实际开发中,针对这个也有很多很好的解决方案,这个可以baidu或者google(说道此,满眼是泪,希望博友可以 提供海量无需FQ即可访问google的网址 ,在此不胜感激!!!)。我在这里引用 WebMagazine 网站一个解决方案,只要代码如下: ---------------------------------------------------------------------HTML标签--------------------------------------------------------------------------------------------------- <div class="file-wrapper"> ---------------------------------------------------------------------jQuery----------------------------------------------------------------------------------------------------- <script src="jquery.js"></script> ---------------------------------------------------------------------Css--------------------------------------------------------------------------------------------------------- <style type="text/css">
在ASP.NET Web开发中,这也不是什么新问题,在这里我想既然说到了文件上传,那么不得不在老调重弹一下,而且网上虽说对于这个问题早有定论,但是还是会看到不少对ASP.NET和IIS默认限制大小的具体说法有些混乱。测试环境为iis7+asp.net 4.0。
另外更糟糕的是甚至会出现这种情况: 从不同的错误页面不难看出,asp.net 默认限制上传大小不超过4M,运行时间不超过90s(因此会出现第三种错误的页面),iis7环境下为30M,超过默认设置,IIS会认为用户是在恶意攻击,因此会拒绝请求。当然微软考虑到上传到文件的需求,因此这个问题是可以通过配置解决的。那么针对它们的解决办法: ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Note1:关于此问题的更详细的解决办法,可以参考 Large File Upload in IIS。 Note2:不仅如此ASP.NET和IIS对其它的诸如QueryString、Url也都有限制。比方说,当文本框输入的字节超过2048个字节的时候同样会引发异常。我想之所以网上关于这个问题的解读会出现偏差可能是这于这两者没有仔细查看的缘故吧。我想如果是这样的话,那么我们就需要仔细看看这两个配置借点的相信阐述了: httpRuntime、 requestFiltering。 Part 4 拓展 另外说到这么多file的问题,其实我们常常看到有些网站会有上传进度条、图片剪切、拖曳上传、异步上传等,而如果要在file基础上实现这个,还是有点麻烦的。我们使用第三方组件来实现。这个在百度上也能找到能多既有的方案。我推荐一个能够实现多文件和进度条上传的组件 jQuery Multiple File Upload with Progress bar Tutorial 。文件上传的 jQuery File Upload Demo 以及 jQuery File Upload 。唉,好的插件确实是太多了,看得我眼花缭乱,不禁要感叹,再也不用担心文件上传了。根据自己的需要选择吧。 Part 5 参阅链接 http://www.codeproject.com/Articles/442515/Uploading-and-returning-files-in-ASP-NET-MVC http://weblogs.asp.net/bryansampica/AsyncMVCFileUpload http://ajaxuploader.com/large-file-upload-iis-asp-net.htm http://ajaxuploader.com/large-file-upload-iis-asp-net.htm http://msdn.microsoft.com/zh-cn/library/ms689462.aspx Part 6 The end 注:由于个人技术有限,对某些概念的理解可能会存在偏差,如果你发现本文存在什么bug,请指正。谢谢! |
MVC&WebForm对照学习:文件上传(以图片为例)的更多相关文章
- MVC&WebForm对照学习:文件下载
说完了WebForm和MVC中的文件上传,就不得不说用户从服务器端下载资源了.那么今天就扯扯在WebForm和MVC中是如何实现文件下载的.说起WebForm中的文件上传,codeshark在他的博文 ...
- THINKPHP源码学习--------文件上传类
TP图片上传类的理解 在做自己项目上传图片的时候一直都有用到TP的上传图片类,所以要进入源码探索一下. 文件目录:./THinkPHP/Library/Think/Upload.class.php n ...
- Spring4 MVC 多文件上传(图片并展示)
开始需要在pom.xml加入几个jar,分别是 <dependency> <groupId>commons-fileupload</groupId> <art ...
- Spring MVC(四)文件上传
文件上传步骤 1.写一个文件上传的页面 2.写一个文件上传的控制器 注意: 1.method="post" 2.enctype="multipart/form-data& ...
- spring mvc 3.0 实现文件上传功能
http://club.jledu.gov.cn/?uid-5282-action-viewspace-itemid-188672 —————————————————————————————————— ...
- Spring MVC—拦截器,文件上传,中文乱码处理,Rest风格,异常处理机制
拦截器 文件上传 -中文乱码解决 rest风格 异常处理机制 拦截器 Spring MVC可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能,自定义的拦截器必须实现HandlerI ...
- webform文件上传、图片水印、验证码
文件上传: 所用控件:FileUpload 使用时的思路: 1.判断用户是否选中了文件 FileUpload.FileName获取选中的文件名,判断长度,如果长度大于零就代表已经选择了文件 JS端:通 ...
- SpringMVC学习--文件上传
简介 文件上传是web开发中常见的需求之一,springMVC将文件上传进行了集成,可以方便快捷的进行开发. springmvc中对多部件类型解析 在 页面form中提交enctype="m ...
- [六]SpringMvc学习-文件上传
1.单文件上传 1.1修改配置文件 <bean id="multipartResolver" class="org.springframework.web.mult ...
随机推荐
- js基础之弹性运动(四)
一.滑动菜单.图片 var iSpeed=0;var left=0;function startMove(obj,iTarg){ clearInterval(obj.timer);//记得先关定时器 ...
- 带你揭开ATM的神秘面纱
相信大家都用过ATM取过money吧,但是有多少人真正是了解ATM的呢?相信除了ATM从业者外了解的人寥寥无几吧,鄙人作为一个从事ATM软件开发的伪专业人士就站在我的角度为大家揭开ATM的神秘面纱吧. ...
- TopCoder SRM 583 TurnOnLamps
读错题了有没有呀,原来 lamps 是在边上的呀,当成是在点上的了,无语. 直接一个dfs 就可以 从叶子节点开始,如果有必要转换 lamp 的状态则加一个仅包含 这个 lamp 的段 然后向上扩展, ...
- node.js安装及grunt插件,如何进行脚本压缩
http://gruntjs.com/pluginshttp://gruntjs.com/getting-startedhttp://gruntjs.com/configuring-tasks#glo ...
- WP8.1 Study4:WP8.1中控件集合应用
1.AutoSuggestBox的应用 在xaml里代码可如下: <AutoSuggestBox Name="autobox" Header="suggestion ...
- FZU 2082 过路费
树链剖分模板题 #include <cstdio> #include <iostream> #include <cstring> #include <algo ...
- hdu 1034 (preprocess optimization, property of division to avoid if, decreasing order process) 分类: hdoj 2015-06-16 13:32 39人阅读 评论(0) 收藏
IMO, version 1 better than version 2, version 2 better than version 3. make some preprocess to make ...
- CCNA 6.9
page 201 show ip route Correction(05-4) Basic configuration of R1: enable configure terminal ...
- 2016 - 1- 22 img tag and the lists (intro to HMTL&CSS)
1 :The img tag img tag allows put some img file into page. just like : <a href = "me.png&quo ...
- Osmocom-BB MOTO C118硬刷
写在最前面,先知我YY下硬刷最好可能实现的功能: 1.把软件刷入flash,修改loader后,可以实现上电就自动运行程序: 2.硬刷后,程序自动起来,可以修改loader就行加密 3.硬刷后,有可能 ...