泛型處理常式的應用 巧妙管理你的binary(max)

泛型處理常式的應用 巧妙管理你的binary(max)

介紹到了ashx, 就不能不提到最常的應用,  管理圖片跟檔案下載

 

還記得我在很蔡的時候,  說要讓人上傳檔案跟圖片

只會拙拙的開一個資料夾存檔案

 

然後要的時候在去那個資料夾撈資料

 

這樣做是有好處啦

不過問題也不少

 

例如說資料夾權限問題,  異地開發檔案不同步的問題,  或是莫名其妙資料不見找不到的問題

 

 

而我們有另外一個選擇, 把這些資料存到資料庫裡面的varbinary(max)

 

當然這樣也是會產生其他的問題啦 例如資料庫暴肥之類的

 

但是我個人是覺得利大於弊, 尤其權限的控管更因此變得很容易

 

(當然2008之後多的FileStream把一切問題都解決了,  這是題外話,  表過不提)

 

 

而在把資料放到資料庫之後,  面臨到的第一個問題就是:  資料要怎麼拿出來

這個時候,  泛型處理常式就出現他的威力

 

 

先拿一個最簡單的案例好了,  我們存了一堆二進位的資料在資料庫裡面

我們希望那張圖片就跟一張一般的圖片秀在頁面上

我們要怎麼下這個標籤呢

 

<img src='……….死掉

 

這個時候我們要用的就是給他的位置導向ashx, 要怎麼做呢

 

可以先來看一下ashx的程式要怎麼寫


public void ProcessRequest(HttpContext context)
{
    string szItemId = context.Request.QueryString["itemId"] ?? string.Empty; //傳入的參數
	if (string.IsNullOrEmpty(szItemId)) return;
	
	int nItemId = -999;
	if (!int.TryParse(szItemId, out nItemId) || nItemId <= 0) return;

	Image img = new Image(nItemId); //這是我經過Entity化的資料表物件, 裡面對應到資料表的欄位
	//image.ImageStream 這個屬性就是對應到資料表的varbinary(max)屬性
	
	if (img == null) return;
	HttpContext.Current.Response.ContentType = string.Format("image", image.ImageType);
	HttpContext.Current.Response.BinaryWrite(image.ImageStream);
	HttpContext.Current.Response.End();
}

 

可以看到程式非常的簡單,

就是傳入一個Id, 撈出一個物件, 把二進位的資料寫進BinaryWrite, 指定好ContentType這樣就好了

 

這個時候再回來寫剛剛的img標籤

<img src='src="../Image/ReadFromData.ashx?itemId=31' />

 

很簡單吧

 

 

而看到這個程式碼,  我們就會開始動腦筋

我們是不是可以在讀資料的同時加上權限判斷

 

有權限的才能做,  沒權限的就不行呢

又或著是更多的創意, 就是我們程式設計師開始熱血沸騰的時候了

 

(題外化,  要加入Session要額外加程式,  這邊就不多提,  直接貼上我google到的第一個網址

  http://www.cnblogs.com/regedit/archive/2007/04/11/707970.html  )

 

 

舉一反三,  檔案要怎麼做呢

 

不多囉唆, 一樣直接貼程式碼


public void ProcessRequest(HttpContext context)
{
    string szItemId = context.Request.QueryString["itemId"] ?? string.Empty; //傳入的參數
	if (string.IsNullOrEmpty(szItemId)) return;
	
	int nItemId = -999;
	if (!int.TryParse(szItemId, out nItemId) || nItemId <= 0) return;
	
	MyFile file = new MyFile(nItemId);
	
	if (file == null)
	{
		context.Response.ContentType = "application/octet-stream";
		context.Response.AppendHeader("Content-Disposition", "attachment;filename=error");
		return;
	}
	context.Response.ContentType = "application/octet-stream";
	context.Response.AppendHeader("Content-Disposition", "attachment; filename=" + string.Format("{0}.{1}", file.FileName, file.FileExt));
	context.Response.BinaryWrite(file.FileContent);

	HttpContext.Current.Response.End();
}

 

可以看到檔案大同小異,  唯一的差別只有最後寫入Binary的地方不太一樣而已

也就是說 ContentType有哪些,  一般來說ashx就可以做哪些事了  (誇飾)

 

寫html的時候其實跟img大同小異

 

唯一特別要提的是,

有的時候我們希望使用者點了button之後下載檔案,  那要怎麼做呢

 

很直覺


function(itemId) {
     location.href = '../File/Download.ashx?itemId=' + itemId;
}

 

這樣就可以了,  而且不會換頁喔

 

不過要是沒有這個檔案基本上還是會換頁啦,  所以最好做個特別處理

例如找不到檔案就給他一個error.txt之類的

 

--

本文可能有理解錯誤  或不盡不實的地方

請路過的前輩不要客氣  用力打醒

這會是我們成長的主要養分