在論壇裡看到有人提出這樣的問題,圖片以 Binary 存於資料庫裡,在頁面上顯示時,如果頁面上要顯示多張圖片時,就會向資料庫多次讀取資料,所以詢問是否有無比較有效率的方式。
其實就我實務上的經驗,除非是遇到沒有提供儲存空間的情況而把圖片以 Binary 存於資料庫的情況,不然我還是會以一般的作法將圖片存在磁碟或是指定位置裡,畢竟資料庫還是儲存資料就好,還是不希望資料庫有其他的用途。
這篇文章就以 Northwind 的 Category 來做示範,因為手邊就只有這個資料庫裡有現成的 Binary 圖片資料可用,將會幾個例子來說明可用什麼樣的方式來處理。
方式一:一般使用情境
首先來看看 Northwind Category 這個 Table 裡的內容,
如果我們要在頁面上顯示 Category 資料以及圖片的話,一般會用以下的處理方式,在 CategoryController 李另外建立一個 GetImage 方法,由前端傳進 Category ID 然後再去從資料庫裡取得 Image 資料,最後再以 MemoryStream 的 Write 方法,將 Binary 資料寫入至資料流裡,然後以 FileContentResult 傳回,
而前端頁面上的使用方式如下:
顯示結果:
但是這樣的方式會對資料庫增加讀取次數,所以不是一個有效率的方式。
方式二:在頁面上增加程式處理
而我們在 CategoryController 的 Index 方法裡是將 Category 資料傳至檢視頁面,所以也已經有把圖片資料傳到頁面,所以我們可以用以下的方式來顯示圖片資料,
這樣就不必再去使用到 CategoryController 的 GetImage 方法,也就不會有向資料庫讀取多次的情況出現,不過這樣的方法並不是很好,可以用 Razor @function 的方式來做進一步的改進。
方式三:使用 Razor @functions
將上面的程式改使用 Razor @functions 的方式來做處理,這樣一來在頁面的 HTML 裡就不夾雜過多的程式,
而使用的方式如下:
這樣就結束了嗎?
還沒,還可以更精進一些,可以把這一段顯示 Binary 圖片資料的處理改寫成 Html Helper,這樣一來後續有需要顯示 Binary 圖片資料的時候就可以直接使用 Html Helper。
方式四:自訂 Html Helper
將上面的 Razor @functions 程式內容改寫為 Html Helper,如下:
檢視頁面的使用,先在檢視頁面上方加入 Namespace 的使用,
而使用 DisplayImage Html Helper 的方式如下:
以上的方式二、三、四,都是將 Binary 圖片資料轉成 base64 的格式,在網頁的原始碼裡就可以看到下的內容,
如果不想輸出這樣的內容,可以參考「DeVCURRY - ASP.NET MVC - Displaying Images using Custom Html Helper Method」這篇文章裡的作法。
「DeVCURRY - ASP.NET MVC - Displaying Images using Custom Html Helper Method」這篇文章裡的作法是會將 Binary 圖片資料給轉為實體圖檔並存於 Images 目錄裡,而圖片在每次執行 ImageData 這個方法時都會重新建立一次然後覆蓋原來的檔案,所以如果你要參考使用這個方法時,可以在程式裡增加圖片檔案是否存在的判斷,這樣一來就不會一直重複建立圖檔。
透過以上幾種處理方式就可以了解如何在檢視頁面上顯示存於資料庫裡的 Binary 圖片資料。
參考連結:
MSDN - MemoryStream.Write 方法 (System.IO)
ASP.NET MVC: Display Images Directly From The ViewModel Into Your Views
DeVCURRY - ASP.NET MVC - Displaying Images using Custom Html Helper Method
以上
沒有留言:
張貼留言