日期:2009-12-30  浏览次数:20458 次

如果你仅仅只有Asp.net Web Forms背景转而学习Asp.net MVC的,我想你的第一个经历或许是那些曾经让你的编程变得愉悦无比的服务端控件都驾鹤西去了.FileUpload就是其中一个,而这个控件的缺席给我们带来一些小问题。这篇文章主要说如何在Asp.net MVC中上传文件,然后如何再从服务器中把上传过的文件下载下来.
在Web Forms中,当你把一个FileUpload控件拖到设计器中,你或许没有注意到在生成的HTML中会在form标签中加入一条额外属性enctype="multipart/form-data". 而FileUpload控件本身会生成为<input type=”file” />,在MVC的view里,有许多种方法可以做到同样效果,第一种的HTML如下:
    <form action="/" method="post" enctype="multipart/form-data"> 
      <input type="file" name="FileUpload1" /><br /> 
      <input type="submit" name="Submit" id="Submit" value="Upload" /> 
    </form> 

注意form标签已经包括了enctype标签,而method属性则设为”post”,这样设置并不多于因为默认的提交时通过HTTP get方式进行的。下面这种方式,使用Html.BeginForm()扩展方法,会生成和上面同样的HTML:
    <% 
      using (Html.BeginForm("", "home", FormMethod.Post, new {enctype="multipart/form-data"}))  
       {%>  
         <input type="file" name="FileUpload1" /><br /> 
         <input type="submit" name="Submit" id="Submit" value="Upload" /> 
    <% }%> 
现在我们可以浏览本地文件然后通过Upload提交按钮将文件提交到服务器端,下一步就是在服务器端处理上传的文件,在使用fileUpload控件时,你可以很轻松的通过FileUpload的hasFile方法来查看文件是否被上传。但是在Asp.net MVC中貌似就不是这么方便了,你会和原始的HTTP更接近一些,然而,一个扩展方法可以处理这些:
    public static bool HasFile(this HttpPostedFileBase file) 
    { 
      return (file != null && file.ContentLength > 0) ? true : false; 
    }  

当你看到对应的Controller类的代码时,你会发现Request对象作为HttpRequestBase类型的一个属性存在。HttpReuqestBase其实是HTTP请求的一个封装,暴漏了很多属性,包括Files collection(其实是HttpFileCollectionBase的集合),在集合中的每一个元素都是HttpPostedFileBase的集合,扩展方法是用于确保上传的文件是否存在。实际上,这和FileUpload.HasFile()方法的工作原理一致。
在Controller Action中使用起来其实很容易:
    public class HomeController : Controller 
    { 
      public ActionResult Index() 
      {