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 ...
随机推荐
- 下拉刷新列表添加SwipeDismissListViewTouchListener实现滑动删除某一列。
<Android SwipeToDismiss:左右滑动删除ListView条目Item> Android的SwipeToDismiss是github上一个第三方开源框架(github上的 ...
- ASP.NET MVC4 部分视图
ASP.NET MVC4 部分视图 2014-10-24 16:48 by 易code, 2662 阅读, 1 评论, 收藏, 编辑 [部分视图] ASP.NET MVC 里的部分视图,相当于 Web ...
- Js中 关于top、clientTop、scrollTop、offsetTop的用法
网页可见区域宽: document.body.clientWidth;网页可见区域高: document.body.clientHeight;网页可见区域宽: document.body.offset ...
- tableview 刷新 @property属性的用法
1.tableView的刷新1> 数据刷新的总体步骤* 修改模型数据* 刷新表格(刷新界面) 2> 刷新表格(刷新界面)的方法* 全局刷新(每一行都会重新刷新)- (void)reload ...
- 最大子段和-Program A
最大子段和 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Description G ...
- 后台获取不规则排列RadioButton组的值
获取多个RadioButton的值,我们一般会使用服务器控件RadioButtonList: <asp:RadioButtonList ID="rbl" runat=&quo ...
- 【kate总结】Matlab坐标轴问题
[kate总结]Matlab坐标轴问题 总结而言 行óYó高ó垂直 列óXó宽ó水平 Maplab中存有2张图片 1.JPG 宽(列):320 高(行):482 在matlab中显示 2.JPG ...
- [C/C++]数据类型与变量
1.类型: 1.1.简介 1.1.1.基本类型(base type)和复合类型(compound type): 复合类型是指基于其它类型定义的类型.([1].2.3 p45)那么基本类型就是复合类型基 ...
- SharePoint表单和工作流 - Nintex篇(四)
博客地址 http://blog.csdn.net/foxdave 接上篇点击打开链接 "Manage workflow constants" 管理工作流常量.这里可以管理工作流中 ...
- PAT 05-树7 File Transfer
这次的题让我对选择不同数据结构所产生的结果惊呆了,一开始用的是结构来存储集合,课件上有现成的,而且我也是实在不太会,150ms的时间限制过不去,不得已,看到这题刚好可以用数组,结果7ms最多,有意思! ...
FileUpload服务器控件 


(注1)

完整代码下载


