MVC之文件上传

前言

这一节我们来讲讲在MVC中如何进行文件的上传,我们逐步深入,一起来看看。

Upload File(一)

我们在默认创建的项目中的Home控制器下添加如下:

        public ActionResult UploadFile()
{
return View();
} [HttpPost]
public ActionResult UploadFile(HttpPostedFileBase file)
{
var fileName = file.FileName;
var filePath = Server.MapPath(string.Format("~/{0}", "File"));
file.SaveAs(Path.Combine(filePath, fileName));
return View();
}

在 UploadFile 视图中添加上如下:

<form action="/Home/UploadFile" method="post" enctype="multipart/form-data">
<input type="file" name="file" /><br />
<input type="submit" value="提交" />
</form>

有关视图中我们就不必多说,只需明白如下两点:

(1)在后台利用HttpPostedFileBase来接收上传文件,该类为一个抽象类,但在ASP.NET Web Form却没有此类,此类的出现是为了更好的进行单元测试。

(2)在视图中文件类型的name要和后台接收文件的参数一致。

接下来我们进行演示看看结果:

 上述我们简单的上传了一个Excel文件,下面我们通过强类型视图以及模型验证来强化上传。

Upload File(二)

我们创建如下BlogModel类:

    public class BlogModel
{
[Display(Name = "博客名称")]
[Required(ErrorMessage = "请输入你的博客名称!")]
public string BlogName { get; set; } [Display(Name = "博客地址")]
[Required(ErrorMessage = "请输入你的博客地址!")]
public string BlogAddress { get; set; } [Display(Name = "博客图片")]
[Required(ErrorMessage = "请上传你的博客图片!")]
[ValidateFile]
public HttpPostedFileBase BlogPhoto { get; set; }
}

上述未有验证文件的特性,只能自定义文件特性,如下:

    public class ValidateFileAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
int MaxContentLength = 1024 * 1024 * 4;
string[] AllowedFileExtensions = new string[] { ".jpg", ".gif", ".png", ".pdf" }; var file = value as HttpPostedFileBase; if (file == null)
return false;
else if (!AllowedFileExtensions.Contains(file.FileName.Substring(file.FileName.LastIndexOf('.'))))
{
ErrorMessage = "请上传你的博客图片类型: " + string.Join(", ", AllowedFileExtensions);
return false;
}
else if (file.ContentLength > MaxContentLength)
{
ErrorMessage = "上传图片过大,不能超过4兆 : " + (MaxContentLength / 1024).ToString() + "MB";
return false;
}
else
return true;
}
}

我们可以任意设置上传的文件大小,我们设置为40兆,在配置文件中我们知道 maxRequestLength = 4096 默认是4兆,当然我们可以改变其默认设置。

    <httpRuntime targetFramework="4.5" executionTimeout="1100"  maxRequestLength="40960" />

此时我们接着在控制器中修改上述上传的方法:

        [HttpPost]
public ActionResult UploadFile(BlogModel bModel)
{
if (ModelState.IsValid)
{
var fileName = bModel.BlogPhoto.FileName;
var filePath = Server.MapPath(string.Format("~/{0}", "File"));
bModel.BlogPhoto.SaveAs(Path.Combine(filePath, fileName));
ModelState.Clear();
}
return View();
}

我们接下来看看效果:

咋回事,出状况了看来是我们的文件过大的原因,看了下该文件有接近45兆,而我们却设置的是40兆,于是乎继续在配置文件中去修改文件大小,但是结果还是一样。我们继续仔细看看该结果的提示,根据提示去找到配置文件下的节点再试试,我们在 syste.webServer 节点下设置为2G:

    <security>
<requestFiltering>
<requestLimits maxAllowedContentLength="2147483647">
</requestLimits>
</requestFiltering>
</security>

结果就好使了,查了查也有遇到类似问题的人,貌似只有给个结果,却没有给解释,为什么在 httpRuntime 中设置不行,但是有些这样设置是正确的,这是什么原因?最终找到了答案:

(1)在IIS 5和IIS 6中,默认文件上传的最大为4兆,当上传的文件大小超过4兆时,则会得到错误信息,但是我们通过如下来设置文件大小。

<system.web>
<httpRuntime maxRequestLength="2147483647" executionTimeout="100000" />
</system.web>

(2)在IIS 7中,默认文件上传的最大为28.6兆,当超过其默认设置大小,同样会得到错误信息,但是我们却可以通过如下来设置文件上传大小。

<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="2147483647" />
</requestFiltering>
</security>
</system.webServer>

【类推的话,个人觉得可能是在IIS 7+以上都是通过如上述IIS 7来设置文件上传大小】

虽然我们在服务器端对其进行验证,但是我们觉得这样还是不能保险,我们继续在客户端对其上传的图片类型和大小进行验证。

(1)利用强类型视图给出视图代码:

<style type="text/css">
.field-validation-error {
color: red;
}
</style>
<form id="uploadFileSub" action="/Home/UploadFile" method="post" enctype="multipart/form-data">
<fieldset>
<legend></legend>
<ul class="lifile">
<li>
@Html.LabelFor(m => m.BlogName)<br />
@Html.TextBoxFor(m => m.BlogName, new { maxlength = 50 })
@Html.ValidationMessageFor(m => m.BlogName)
</li>
<li>
@Html.LabelFor(m => m.BlogAddress)<br />
@Html.TextBoxFor(m => m.BlogAddress, new { maxlength = 200 })
@Html.ValidationMessageFor(m => m.BlogAddress)<br />
</li>
<li>
@Html.LabelFor(m => m.BlogPhoto)
@Html.TextBoxFor(m => m.BlogPhoto, new { type = "file" })
@Html.ValidationMessageFor(m => m.BlogPhoto)
<span id="warning" style="color:red;font-size:large;"></span>
</li>
<li>
<input type="submit" value="提交" />
</li>
</ul> </fieldset>
</form>

(2)利用脚本获取上传文件大小:

    function GetFileSize(fileid) {
var fileSize = 0;
fileSize = $("#" + fileid)[0].files[0].size;
fileSize = fileSize / 1048576;
return fileSize;
}

(3)根据上传的路径获取文件名称:

    function getNameFromPath(strFilepath) {
var objRE = new RegExp(/([^\/\\]+)$/);
var strName = objRE.exec(strFilepath); if (strName == null) {
return null;
}
else {
return strName[0];
}
}

(4)当更换文件时触发Change事件对其文件类型和文件大小进行验证:

        $("#BlogPhoto").change(function () {
var file = getNameFromPath($(this).val());
if (file != null) {
var errors = $(document).find(".field-validation-error");
$.each(errors, function (k, v) {
if ($(v).attr("data-valmsg-for") === "BlogPhoto") {
$(v).hide();
}
});
var extension = file.substr((file.lastIndexOf('.') + 1));
switch (extension) {
case 'jpg':
case 'png':
case 'gif':
case 'pdf':
fileTypeBool = false;
break;
default:
fileTypeBool = true;
}
}
if (fileTypeBool) {
$("#warning").html("只能上传扩展名为jpg,png,gif,pdf的文件!");
return false;
}
else {
var size = GetFileSize('BlogPhoto');
if (size > 4) {
fileSizeBool = true;
$("#warning").html("上传文件已经超过4兆!");
} else {
fileSizeBool = false;
}
}
});

(5)当点击提交按钮时对其进行文件进行验证:

        $("#uploadFileSub").submit(function () {
$("input[type='text']").each(function (k, v) {
if ($(v).length) {
$(v).siblings("span").hide();
}
});
if (fileTypeBool || fileSizeBool) {
return false;
}
});

【注意】上述对于验证不是太完整,但是基本的架子已经给出。

接下来我们来完整的演示整个过程。

上述我们一直是利用的纯HTML代码,当然也可以利用MVC的扩展方法来进行,如下(最终渲染的还是表单,本质上是一致的,就不做过多探讨了)

@using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{ <input type="file" id="file" name="file" />
<input type="submit" value="提交" />
}

结语

这一节我们比较详细的讲述了在MVC中如何进行文件的上传,但是我们还有一点未曾讲到,则是利用流来将如我们上述的图片转换成字节来插入到数据库中。有关上传可以参考园友Insus.NET对此利用流来上传。

MVC之文件上传1的更多相关文章

  1. Spring MVC实现文件上传

    基础准备: Spring MVC为文件上传提供了直接支持,这种支持来自于MultipartResolver.Spring使用Jakarta Commons FileUpload技术实现了一个Multi ...

  2. Asp.net mvc 大文件上传 断点续传

    Asp.net mvc 大文件上传 断点续传 进度条   概述 项目中需要一个上传200M-500M的文件大小的功能,需要断点续传.上传性能稳定.突破asp.net上传限制.一开始看到51CTO上的这 ...

  3. Spring MVC的文件上传

    1.文件上传 文件上传是项目开发中常用的功能.为了能上传文件,必须将表单的method设置为POST,并将enctype设置为multipart/form-data.只有在这种情况下,浏览器才会把用户 ...

  4. Spring MVC的文件上传和下载

    简介: Spring MVC为文件上传提供了直接的支持,这种支持使用即插即用的MultipartResolver实现的.Spring MVC 使用Apache Commons FileUpload技术 ...

  5. 整合MVC实现文件上传

    1.整合MVC实现文件上传整合MVC实现文件上传在实际的开发中在实现文件上传的同时肯定还有其他信息需要保存到数据库,文件上传完毕之后需要将提交的基本信息插入数据库,那么我们来实现这个操作.整个MVC实 ...

  6. 【Spring学习笔记-MVC-13】Spring MVC之文件上传

    作者:ssslinppp       1. 摘要 Spring MVC为文件上传提供了最直接的支持,这种支持是通过即插即用的MultipartResolve实现的.Spring使用Jakarta Co ...

  7. MVC图片上传、浏览、删除 ASP.NET MVC之文件上传【一】(八) ASP.NET MVC 图片上传到服务器

    MVC图片上传.浏览.删除   1.存储配置信息 在web.config中,添加配置信息节点 <appSettings> <add key="UploadPath" ...

  8. spring mvc ajaxfileupload文件上传返回json下载问题

    问题:使用spring mvc ajaxfileupload 文件上传在ie8下会提示json下载问题 解决方案如下: 服务器代码: @RequestMapping(value = "/ad ...

  9. 0062 Spring MVC的文件上传与下载--MultipartFile--ResponseEntity

    文件上传功能在网页中见的太多了,比如上传照片作为头像.上传Excel文档导入数据等 先写个上传文件的html <!DOCTYPE html> <html> <head&g ...

随机推荐

  1. [置顶] ArcGIS发布最新的 ArcGIS Runtime SDK for Android v10.1.1

    因为希望有统一的地图解决方案,就是PC端,移动端的数据一致,看到ArcGIS的最新发布,感兴趣的可以围观. 链接:http://blogs.esri.com/esri/arcgis/2013/09/0 ...

  2. 【Android】 -- 使用UncaughtExceptionHandler捕捉全局异常

    在综合统计SDK(欧盟统计局的朋友,百度统计)之后.有一个非常有利的功能测试:错误分析.此功能可以在程序的执行中遇到崩溃(runtimeException)反馈给server,帮助开发者提高产品.多功 ...

  3. 使用SetLocaleInfo设置时间后必须调用广播WM_SETTINGCHANGE,通知其他程序格式已经更改

    uses messages; Procedure SetDateFormat; //设置系统日期格式var buf:pchar; i:integer; p:DWORD;begin getmem(buf ...

  4. const限定符的作用

    const限定符的作用:                                     1.定义const常量:const可以将一个对象变成一个常量,不可被修改,所以定义的 时候必须进行初始 ...

  5. 14.6.2 Moving or Copying InnoDB Tables to Another Machine 移动或者copy InnoDB 表到另外的机器

    14.6.2 Moving or Copying InnoDB Tables to Another Machine 移动或者copy InnoDB 表到另外的机器 这个章节描述技术关于移动或者copy ...

  6. perl 使用cookie

    use Net::SMTP; use LWP::UserAgent; use HTTP::Cookies; use HTTP::Headers; use HTTP::Response; use Enc ...

  7. 内核编程实例,多文件的Makefile

    内核编程实例,多文件的Makefile 经典的hello word测试 ////# cat hello.c #include <linux/module.h> #include <l ...

  8. c++ virturn function -- 虚函数

    c++ virturn function -- 虚函数 pure irtual function  -- 纯虚函数   先看例子 #include <iostream> using nam ...

  9. c friend -- 友元

    c friend -- 友元 友元用于突破protected 或者 private 保护的限制,首先要做的是在被访问者的类中声明是友元函数或者友元类.代码如下 #include <iostrea ...

  10. Swift - 下标脚本方法介绍及实例

    定义下标脚本之后,可以使用“[]”来存取数据类型的值. 示例1:实现一个我们自定的字符串类,可以方便的通过索引获取某一个字符值,或某一部分字符串.同时也可以通过索引,给某一部分赋值. 1 2 3 4 ...