如果你僅僅只有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" />
<% }%>
注意<input type=”file”>標簽的name屬性,我們在後面再討論,上面代碼會如下圖:
OK,現在我們可以浏覽本地文件然後通過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()
{
foreach (string upload in Request.Files)
{
if (!Request.Files[upload].HasFile()) continue;
string path = AppDomain.CurrentDomain.BaseDirectory + "uploads/";
string filename = Path.GetFileName(Request.Files[upload].FileName);
Request.Files[upload].SaveAs(Path.Combine(path, filename));
}
return View();
}
}