您现在的位置是:探索 >>正文

asp net mvc 上传文件

探索8376人已围观

简介ASP.NET MVC里传文件,坑比想象的多。前几天帮朋友调一个报修系统,前端明明选了图片,后端就是收不到,最后发现是表单里忘了加enctype="multipart/form-data"。这行代码漏 ...

ASP.NET MVC里传文件,传文坑比想象的传文多。前几天帮朋友调一个报修系统,传文前端明明选了图片,传文后端就是传文收不到,最后发现是传文表单里忘了加enctype="multipart/form-data"。这行代码漏了,传文整个请求体就变成普通文本格式,传文服务器端Request.Files永远是传文空的。

先看最基础的传文写法。视图里得有个表单,传文用Html.BeginForm指定action和controller,传文第三个参数传FormMethod.Post,传文还要额外塞一个new { enctype = "multipart/form-data" }。传文别嫌麻烦,传文这是HTTP协议规定的,文件数据得用multipart格式分段传输。输入框用,注意name属性必须跟控制器方法的参数名对上,不然绑定不上。

控制器端接收有两种路子。一种是直接拿HttpPostedFileBase参数,MVC模型绑定器会自动帮你从请求里解析出来。另一种是手动从Request.Files里取,灵活但代码丑。我偏好前者,干净。示例代码:

public ActionResult Upload(HttpPostedFileBase file) {  if (file != null && file.ContentLength > 0) {  var fileName = Path.GetFileName(file.FileName); var savePath = Path.Combine(Server.MapPath("~/App_Data"), fileName); file.SaveAs(savePath); ViewBag.Message = "上传成功"; } return View(); } 

这段代码能跑,但生产环境直接这么写会出事。文件名没做唯一化处理,两个用户传同名文件会互相覆盖。得加个GUID或者时间戳:var newName = Guid.NewGuid().ToString() + Path.GetExtension(file.FileName);。还有路径穿越漏洞,用户传个../../web.config之类的文件名,直接拼接路径就能覆盖你服务器上的配置文件。虽然现代浏览器会过滤掉路径部分,但防不住有人用curl模拟请求。

文件大小限制也是个坑。IIS默认请求体上限是30MB左右,超过就报404.13错误。改web.config里httpRuntime maxRequestLength(单位KB)和security > requestFiltering > requestLimits maxAllowedContentLength(单位字节)两个地方。但别盲目调大,得权衡服务器内存。文件太大建议走流式处理,别用SaveAs一把梭——那玩意儿会把整个文件加载进内存,图片还好,视频文件直接OOM。

异步上传是另一个话题。用Ajax.BeginForm配合jquery.unobtrusive-ajax库,能实现无刷新上传,但进度条得自己写。HTML5的XMLHttpRequest支持upload.onprogress事件,可以实时显示百分比。MVC 5里还能用HttpPostedFileBase配合Request.Files.GetMultiple()做多文件上传,前端input加multiple属性,后端循环处理。

最后说个容易忽略的点:上传文件的Content-Type校验。别只依赖扩展名判断文件类型,攻击者可以把exe改成jpg骗过服务器。最好用Path.GetExtension白名单过滤,再读取文件头几个字节做魔数校验。比如JPEG开头是FF D8 FF,PNG是89 50 4E 47。虽然麻烦点,但比起被挂马,这点成本不值一提。

实际项目里我还会把上传记录写进数据库,存原始文件名、存储路径、上传时间、上传人。这样以后排查问题或者做审计都有据可查。存文件路径而不是直接把文件存数据库——数据库别当文件系统用,性能差还占空间。

这套流程走完,基本能覆盖日常需求。真遇上超大文件或者断点续传那种场景,MVC自带的玩意就不够用了,得上Plupload或者Resumable.js这类专门组件,配合服务端分片接收。但那是另一个故事,今天到这打住。

Tags:

相关文章

  • 旗米垃首页

    探索

    旗米垃首页打开的时候,我第一反应是“这玩意儿怎么这么白”。白得刺眼,白得空旷,像是有人把一张A4纸拉伸成了网页,然后随手丢了几块色块上去。但多看了两眼,又觉得这种白不是偷懒——它像是刻意把舞台清空了, ...

    【探索】

    阅读更多
  • php实战视频教程

    探索

    我见过太多人对着PHP教程犯困。屏幕上的代码在跑,人却神游天外——因为那些教程只教语法,不教思维。真正的PHP实战,是从一个具体问题开始的:比如,你的博客突然被垃圾评论刷屏了。 我去年接手一个老项目, ...

    【探索】

    阅读更多
  • 修改网页源代码犯法么

    探索

    修改网页源代码犯法么?直接说结论:单纯修改自己电脑上看到的网页代码不犯法,但未经授权修改别人服务器上的网页源代码,几乎必然违法。这个区别,很多人搞混了。 先讲个真事。去年有个朋友,做电商运营的,嫌公司 ...

    【探索】

    阅读更多


友情链接