Alan Tsai 的學習筆記


學而不思則罔,思而不學則殆,不思不學則“網貸” 為現任微軟最有價值專家 (MVP)、微軟認證講師 (MCT) 、Blogger、Youtuber:記錄軟體開發的點點滴滴 著重於微軟技術、C#、ASP .NET、Azure、DevOps、Docker、AI、Chatbot、Data Science

[iThome 第七屆鐵人賽 15] 處理檔案上傳

2014-10-07 Tuesday

在網站裡面,通常都會需要讓使用者上傳檔案,好方便前臺或者別的顯示這個資訊的地方來下載這個對應的檔案。

在Mvc裡面,有所謂的HttpPostedFileBase可以方便我們接到前端input是file的檔案。這個檔案通常會被存到Server的某一個位置之後,路勁才會儲存到DB 裡面,下次顯示的時候顯示的是這個檔案的路徑。

處理HttpPostedFileBase的邏輯其實還滿常見,如果框架能夠把這一部份也處理掉的話,又可以減少我們煩惱這些細節的部份,提升開發效率。

這一篇我們將來看一下如何做到。

整體功能概念

我們的Entity欄位通常會是string的形態,用來儲存這個上傳檔案的相對路徑。而檔案上傳方便做model binding是HttpPosedFileBase這個形態,因此我們將會在ViewModel增加一個對應的property用來接使用者所選取的檔案。

我們的邏輯處理規則是需要:

  1. HttpPostedFileBase的檔案存到特定的位置。
  2. 把儲存的檔案相對的路徑存入到正確的欄位裡面。

功能實作

有了上面整體的概念之後,將會開始實作。

欄位說明

假設我們現在的Post需要有一個欄位用來儲存這篇文章的代表圖,因此我們會多一個欄位叫做CoverImg(在ViewModel),同樣對應到DB的Table欄位也是 CoverImg

我們會在多一個欄位叫做CoverImgFile在ViewModel,這個欄位的主要目的是對應到View裡面的HttpPostedFileBase

因此目前Post的定義會是(標亮是新增的兩個欄位):

public partial class Create
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string PostContent { get; set; }
    public System.DateTime CreateDateTime { get; set; }
    public Nullable<System.DateTime> LastModifyDateTime { get; set; }
    public string CoverImg { get; set; }
    public HttpPostedFileBase CoverImgFile { get; set; }
}

View的說明


再來,對應的View會變成:

@if(string.IsNullOrEmpty(Model.CoverImg) == false)
{ 
    <img src="~/@Model.CoverImg" />
}

<input type="file" name="CoverImgFile" />

首先是如果檔案已經有上傳過(表示CoverImg有值),就以圖片方式顯示。


然後CoverImgFile則是實際的檔案上傳。


檔案上傳的處理


Create的地方將會處理檔案上傳並且把路徑存到CoverImg

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Create post)
{
    if(post.CoverImgFile != null)
    {
        var fileName = DateTime.Now.ToString();

        post.CoverImgFile.SaveAs(fileName);

        post.CoverImg = fileName;
    }

    if (ModelState.IsValid)
    {
        service.CreateViewModelToDatabase(post);
        return RedirectToAction("Index");
    }

    return View(post);
}

這邊不管是否有驗證成功,都會把檔案儲存起來,避免Validation錯誤返回Model的時候,之前選的檔案會不存在。


結語


到這裡之後,相信對於如何處理檔案上傳和把檔案路徑放入對應的欄位已經瞭解。


但是,相信使用上面來說不是很方便。首先,寫在Controller裡面這部份的邏輯就很不適合,再來,如果這個邏輯以後要修改或者需要通用基本上做不到。


因此,在下一篇,將會介紹如何透過Service層,把處理檔案上傳的邏輯抽出來,讓這部份的邏輯能夠共用。


如果文章對您有幫助,就請我喝杯飲料吧
街口支付QR Code
街口支付QR Code
台灣 Pay QR Code
台灣 Pay QR Code
Line Pay 一卡通 QR Code
Line Pay 一卡通 QR Code
街口支付QR Code
支付寶QR Code
街口支付QR Code
微信支付QR Code
2014-10-07 Tuesday
comments powered by Disqus