ASP.NET MVC - 上傳檔案至Web Server上

在純HTML中,
可以使用 <input> Element指定type為file就可以瀏覽選擇本機端的檔案,
但問題在於要如何將選擇的檔案傳送至後端的Web Server?
在接下來限量就來公佈如何將檔案傳送至後端。


我們可以使用一般的Form或者使用ASP.Net MVC所提供的Html.BeginForm來傳送檔案與其他輸入值,首先我們先來看看一般的Form。

<form action="@Url.Action("TestFileUpload", "Home")" method="post" enctype="multipart/form-data">
    <input type="file" name="file" id="file" />
    <input type="text" name="test"/>
    <input type="submit" name="submit" value="Submit" />
</form>

這上面action部分限量偷偷用了MVC的Url.Action取得對應Action的Url,
這裡要注意的重點是使用enctype="multipart/form-data",
enctype的Attribute是用來指定Form Data在傳給Server時是否要Encode,
如果傳檔案就要指定enctype="multipart/form-data",
(注意:enctype只有在method="post"的情況下才能使用)

下面是Server端的Code:

[HttpPost]
public ActionResult TestFileUpload( HttpPostedFileBase file, String test )
{
    var path = String.Empty;
    var uploadDir = Server.MapPath( "~/App_Data/Uploads" );
    if ( file != null && file.ContentLength > 0 )
    {
        if ( !Directory.Exists( uploadDir ) )
            Directory.CreateDirectory( uploadDir );
        path = Path.Combine( uploadDir, file.FileName );
        file.SaveAs( path );
    }
    return RedirectToAction("Index", "Home");
}

當按下Submit的按鈕後,
Form Data會傳入到該Action,
這裡承接Form Data的參數名稱必須要和<input> name的值一樣,
檔案類型我們使用HttpPostedFileBase來接,
HttpPostedFileBase是存取Client上傳File相關類別的基底抽象類別,
在VS下監看式可以看到傳進來的file為HttpPostedFileWrapper類別,
HttpPostedFileWrapper則繼承HttpPostedFileBase,
ContentLength為檔案大小(單位為Bytes),
ContentType為檔案類型(Http所識別的檔案類型),



取得檔案資料後就要進行儲存的動作,
先判斷檔案是否為null才能夠儲存,
在這裡限量我為了將儲存的檔案統一放在一個位置,
就使用Directory.CreateDirectory(uploadDir)來建一個資料夾放置檔案,
Directory.CreateDirectory()放的Path要為絕對路徑,
於是我們就要使用Server.MapRath("~/App_Data/Uploads")把相對路徑轉換為絕對路徑,
在這個範例中,我們將在專案底下(~)的App_Data資料夾裡建立Uploads資料夾,
建立資料夾後最後呼叫HttpPostedFileBase所提供的SaveAs(String filename)方法儲存檔案。

這樣看起來是不是相當簡單,
讓我們再來看看ASP.Net MVC Html.BeginForm()的寫法:

@using ( Html.BeginForm( "TestFileUpload", "Home", FormMethod.Post, new { enctype = "multipart/form-data" } ) )
{
    <input type="file" name="file" />
    <input type="text" name="test"/>
    <input type="submit" name="submit" value="Submit" />
}

上面的程式碼雖然是用MVC的寫法,
但產生出來的HTML Code是和前面Form一樣的,
Server端的程式碼也不需要變動。

目前為止看來,上傳檔案相當的簡單,
但如果想要以Ajax的方式上傳檔案呢又該如何做呢?
這點限量只能告訴你,就我Survey過的資料中,
關於Ajax上傳檔案的部分,都強調File Upload在Ajax是不可行的,
但一些瀏覽器在最近的版本中已經提供可經由Ajax上傳檔案,
這個部分就待後續的研究後再公開吧!


參考來源:
W3CSchool enctype Attribute
MSDN HttpPostedFileBase 類別
MSDN HttpPostedFIleWrapper




留言