ASP.NET MVC 文件上传教程(一)

前端技术 2023/09/08 .NET

这一节我们来讲讲在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中如何进行文件的上传,但是我们还有一点未曾讲到,则是利用流来将如我们上述的图片转换成字节来插入到数据库中。

有关上传可以参考这篇文章.NET对此利用流来上传。

作者和原文连接:Recluse_Xpy  http://www.cnblogs.com/CreateMyself/p/5414200.html

以上就是本文的全部内容,希望对大家的学习有所帮助。

本文地址:https://www.stayed.cn/item/20710

转载请注明出处。

本站部分内容来源于网络,如侵犯到您的权益,请 联系我

我的博客

人生若只如初见,何事秋风悲画扇。