泛型處理常式的應用 巧妙管理你的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之類的
--
本文可能有理解錯誤 或不盡不實的地方
請路過的前輩不要客氣 用力打醒
這會是我們成長的主要養分