GridView顯示Database中Binary類型的資料-以圖片配合LINQ為例

GridView顯示Database中Binary類型的資料-以圖片配合LINQ為例

在ASP.NET中GridView是我們的好夥伴,不過,如果你知道怎麼用它的、怎麼把它跟其他控制項(例如:Button、CheckBox、Field
中在放一個Table等)結合著用,那你一定是非常熟悉ASP.NET整個運作架構與GridView的使用高手,但對於像我這種小角色的話,
也許要搭配這麼強大的功能,說實在話,我還真不是一時三刻馬上就能上手的。因此,如果有寫錯的地方,或者是大家知道還有更
厲害的做法,也請大家能不吝嗇的分享給我知道,非常的感謝。接下來進入主題,其實透過GridView要呈現圖片的做法非常多,也
許你有看過直接在DB裡面放圖片的路徑、或者是把它放在一個資料夾,再全部按字母大小順序顯示出來等等,但這一篇要寫的是將
SQL Server中資料欄位為Image型態的圖片顯示在畫面中的GridView上,並且透過LINQ to SQL的方示,把資料擷取出來並顯示於GridView中,
並且結合thickBox的使用。
 
重點觀念:
一、什麼是ASP.NET中的<%# %>與Eval、Bind
       以下是擷取至MSDN的內容:「在ASP.NET中所有的資料繫結運算式都必須包含在 <%# 和 %> 字元之間。另外ASP.NET 支援階層式
資料繫結模型,這種模型會建立伺服器控制項屬性與資料來源之間的繫結。幾乎任何伺服器控制項屬性都可以與容納它的網頁,或是伺服
器控制項之直接命名容器 (Container) 上的任何公用欄位或屬性產生繫結。資料繫結運算式使用 Eval 和 Bind 方法將資料繫結至控制項,並
將變更送回資料庫Eval 方法是一種靜態 (唯讀) 方法,會取得資料欄位的值,並且將其以字串的形式送回Bind 方法支援讀/寫功能並具
有擷取資料繫結控制項之值,以及將所有變更都送回資料庫的能力。」上述說明的內容,針對我們在處理特殊資料顯示,Eval與Bind是特別
需要注意的,因為這些將會用於下方程式範例中針對圖片顯示與處理的內容加以說明。
 
二、LINQ to SQLLINQ
       隨著ASP.NET 3.5推出(可參考提供ASP.NET 3.5 & LINQ to SQL的學習資訊),LINQ已經變成常用於處理資料查詢與運作的好用工具之一,
LINQ的核心透過lambda運算式加以簡化程式的撰寫,並且透過編譯器加以轉換成針對SQL的語言,透過動態的方式加以組合成我們所需要的
SQL針對資料庫或實體進行資料的運作,提供ORM的技術幫助有效的切割傳統直接把SQL語言或資料運作寫到程式裡,也提供實作MVC的另
一種型式。另外LINQ還針對LINQ to XML、LINQ to Object等,而.NET在ORM的技術,還有值得研究的ADO.NET Entity Framework,它也是
個透過建立資料實體的方式,將實體資料處理與程式控制之間,隔出了一層讓我們可以全力開發操作,後端至有Entity Framwork或LINQ幫我
們針對資料型態的Mapping,讓我們程式處理上,透過物件導向的概念,即可完成我們要的工作內容。
 
三、ASP.NET中的.ashx檔
      (參考ASP.NET ASHX Handler Tutorial ),.ashx的用途在於處理Http處理常式,那什麼叫做Http處理常式呢?引述MSDN上的說明,「在
ASP.NET HTTP 處理常式是為了回應對 ASP.NET Web 應用程式所提出之要求而執行的處理序 (通常稱為「端點」)。最普通的處理常式是處理
.aspx 檔案的 ASP.NET 網頁處理常式。當使用者要求 .aspx 檔案時,網頁會透過網頁處理常式處理要求。您可以建立自己的 HTTP 處理常式,
在瀏覽器中呈現自訂輸出。」這樣的好處在於,透過自訂的Http處理常式的運用,我們可以快速的結合,例如:要顯示的圖片、要呼叫的
對Http處理常式所提供的,包括:
 
處理常式
描述
ASP.NET 網頁處理常式 (*.aspx)
所有 ASP.NET 網頁的預設 HTTP 處理常式。
Web 服務處理常式 (*.asmx)
在 ASP.NET 中建立為 .asmx 檔案之 Web 服務網頁的預設 HTTP 處理常式。
泛型 Web 處理常式 (*.ashx)
所有不包含 UI,但包含 @ WebHandler 指示詞之 Web 處理常式的預設 HTTP 處理常式。
追蹤處理常式 (trace.axd)
顯示目前頁面追蹤資訊的處理常式。如需詳細資訊,請參閱 HOW TO:使用追蹤檢視器檢視 ASP.NET 追蹤資訊
HTTP 模組是一個每次在應用程式收到要求時就會被呼叫的組件。HTTP 模組是用來做為 ASP.NET 要求管線的一部分而呼叫,並在整個要求中都有對
生命週期事件的存取權。HTTP 模組可讓您檢查連入與連出要求,並根據要求採取動作。 以上是針對撰寫這一篇內容之前,我自己學習的過程所建立
的一些概念,接下來就要說明,如何透過LINQ to SQL的方式,將資料庫儲存的二進位圖片資料顯示GridView中,最後再補充透過ThickBox的特效,
讓縮小的圖片可以獨立放大。
 
以下將詳細說明開發的重點:
1. 建立一個 data type為image的欄位(以SQL Server Express 2005為例)   
   (a)建立一個Product的資料表,具有ID、Name與Image三個欄位,記得將Image的資料類型選為Image(支援儲存Binary Data)。
 

    0000

2. 建立LINQ to SQL的Data Model
    (a) 新增一個新的項目:選擇LINQ to SQL Classes(請記得更新Visual Studio 2008至SP1),副檔名為:.dbml。   
    (b) 將Prodcut資料表拉進Data  model designer元件中。形成如下圖。(在儲存該檔案時,Visutal Studio會自動建立相關的欄位與Entity、Mapping的
         欄位資料類型等等。)
 

    00010002

3. 建立一個Handler.ashx的檔案
    (a) 新增一個新的項目:選擇Generic Handler,副檔名為:.ashx。(用於aspx中html常式處理的時候,在這次的範例,則是透過它來取得產品的icon,
         並且轉換成Byte[]傳回到畫面中進行顯示。)
 

    0004   

    (b) 建立好檔案之後,針對Generic Handler檔案,我們需要加上要處理的內容:根據產品代號(ID),使用LINQ擷取儲存於資料庫中的產品圖示。
         要特別注意:‧圖片的寫回,要透過BinaryWrite的方式,才能正確寫回到畫面中的Image物件
                            ‧由於database中的image類型,透過LINQ自動產生的Mapping data type是Binary(System.Data.Linq.Binary),而不是byte[],
                                所以需要將透過LINQ取回的image,需要使用toArray()的方式,把他轉型。
   1: public void ProcessRequest (HttpContext context) {
   2:         //context.Response.ContentType = "text/plain";
   3:         //context.Response.Write("Hello World");
   4:         ProductDBDataContext dbProvider = new ProductDBDataContext();
   5:         int prodcutID = int.Parse(context.Request.QueryString["ID"]);
   6:         var result = dbProvider.Products.Single(p => p.ID.Equals(prodcutID));
   7:         context.Response.BinaryWrite((byte[])result.Image.ToArray());        
   8:     }
4. 建立實際操作的網站,並且設定GridView該有的樣子。   
    (a) 在畫面中,拉進一個GridView,並且建立三個固定欄位:2個BoundField(分別DataField為:ID、Name)、1個TemplateField
         (並且在之中加入一個<asp:Image />控制項,如下圖:
 

    003

    (b) 設定完GridView的layout之後呢,要記得加上thickbox使用的設定,包括需要載入javascritp檔、指定那一個物件要用thicbox特效,
         要記得設定他的css class。另外,要讓圖片顯示可以使用thickbox,需透過<a href />來結合圖片物件,如下是gridview的html code:(第10~12行是重要的)。
   1: <asp:GridView ID="GridView1" runat="server" BackColor="White" 
   2:      BorderColor="#3366CC" BorderStyle="None" BorderWidth="1px" CellPadding="4" 
   3:      Width="85%" AutoGenerateColumns="False">
   4:      <RowStyle BackColor="White" ForeColor="#003399" />
   5:        <Columns>
   6:           <asp:BoundField DataField="ID" HeaderText="產品編號" />
   7:           <asp:BoundField DataField="Name" HeaderText="產品名稱" />
   8:           <asp:TemplateField HeaderText="產品圖示">
   9:               <ItemTemplate>
  10:                  <a href='<%# "Handler.ashx?ID="+Eval("ID") %>' class="thickbox">
  11:                    <img border='0' src='<%# "Handler.ashx?ID="+Eval("ID") %>' width="100px" height="60px" /> 
  12:                  </a>
  13:               </ItemTemplate>
  14:           </asp:TemplateField>
  15:        </Columns>
  16:        <FooterStyle BackColor="#99CCCC" ForeColor="#003399" />
  17:        <PagerStyle BackColor="#99CCCC" ForeColor="#003399" HorizontalAlign="Left" />
  18:        <SelectedRowStyle BackColor="#009999" Font-Bold="True" ForeColor="#CCFF99" />
  19:        <HeaderStyle BackColor="#003399" Font-Bold="True" ForeColor="#CCCCFF" />
  20: </asp:GridView>      
5. 修改thickbox.js支援.ashx的Html常式處理
    在jQuery的發展下,網頁開發人員可以透過jQuery與JavaScript的配合,可以開發出非常豐富的畫面處理以及相當於桌面操作的感受,因此,
在thickBox的運用,也讓我們可以做出過去需要透過開一個新的視窗(瀏覽器)才能收看的內容。而要結合這次的使用,因為在thickBox的javascript檔(thickbox.js),
針對特定處理的副檔有特定的使用,以下是原始的code如下:
   1: var urlString = /\.jpg$|\.jpeg$|\.png$|\.gif$|\.bmp$/;
   2: var urlType = baseURL.toLowerCase().match(urlString);
   3:  
   4: iif(urlType == '.jpg' || urlType == '.jpeg' || urlType == '.png' || urlType == '.gif' || urlType == '.bmp'){//code to show images

 

因為這一段主要是判斷你使用接受thickbox的目標是html還是其他圖片類的使用,因此,為了讓我們可以支援.ashx的使用,我們就需要把ashx加到判斷之中。
修改過的code如下:
   1:  
   2: var urlString = /\.jpg$|\.jpeg$|\.png$|\.ashx$|\.gif$|\.bmp$/;
   3: var urlType = baseURL.toLowerCase().match(urlString); 
   4:  
   5: if (urlType == '.jpg' || urlType == '.jpeg' || urlType == '.ashx' || urlType == '.png' || urlType == '.gif' || urlType == '.bmp') {//code to show images 
6. 執行結果

result0 result1

以上是說明如何透過GridView來顯示圖片,並且透過LINQ to SQL的技術將資料從database中取出,並且轉換型別支援byte[],最後,
結合thickbox的特效功能於顯示圖片中,讓內容能更清楚的顯系出來。希望寫這篇,對有興趣學習的人有所幫助,另外,在下方有提
供該範例的程式碼。大家可以參考一下,如果沒有寫好的部分,也請大家指教。感謝。

References:
Displaying Image in Gridview from Database:這一篇主要透過在DB中儲存檔案的路徑,透過GridView中的ImageField.DataImageUrlField來對應並取得資料。
http://blog.blueshop.com.tw/hent/archive/2007/09/18/52472.aspx
http://blog.csdn.net/striveman/archive/2007/09/19/1791039.aspx
http://www.c-sharpcorner.com/UploadFile/jayendra/103092009123618PM/1.aspx
http://blog.blueshop.com.tw/topcat/archive/2008/01/23/54135.aspx
http://blog.blueshop.com.tw/topcat/archive/2006/06/06/27941.aspx

 

Pou's IT Life Tags: , ,