關於我

我的相片
用心思考、保持熱情,把工作上的經驗作分享與紀錄。希望能夠跟大家一起不斷的成長~

各瀏覽器 UpLoadFile.PostedFile.FileName 屬性的差異

今天發現 Asp.net 在 Server 端收到 各瀏覽器 Response 回的UpLoadFile.PostedFile.FileName傳回的值有些差異。
以上傳D:\123.txt為例,各瀏覽器傳回值如下:

  1. IE5:D:\123.txt
  2. IE6:D:\123.txt
  3. IE7:123.txt
  4. IE8:123.txt
  5. Chrome:123.txt
  6. FireFox:123.txt

因此在CodeBehide取值時,要特別注意。會有差異。
可以多使用Path.GetFileName(),便可避免因瀏覽器傳回的差異,而取到不相同的值了!
程式碼如下:

Path.GetFileName(UpLoadFile.PostedFile.FileName);

讓 FCKEditor 的 Link : MailTo 功能,改用 Big5 編碼

FCKEditor 是個很讚的線上編輯器,這模組,可讓我們直接在線上,類似使用frontpage等工具一樣的操作,去編寫一個網頁。因此也被許多論壇所採用!如果有機會,看看FCKEditor的Source,會發現它基本上是個幾乎全部使用Javascript動態產生的環境。真的是嘆為觀止!今天要介紹的是一個在這編輯器上的客製功能。

因為我們慣用語言是中文,中文在編碼上要相當注意,不然時常會發生亂碼的問題,例如FckEditor的Link模組中,可讓我們加入MailTo功能,畫面如下:
1
而編輯器最後便會幫我們在網頁上,加入一個如:mailto:電子郵件地址?subject=主題&body=內文,的連結。而問題也就發生在主題與內文的部分,FCKEditor預設會幫我們把主題與內文的部分,做Javascript的Encode,Encode過得編碼為UTF-8的格式(FCKeditor預設使用encodeURIComponent方法做Encode),但這樣的連結,就必須考慮到讀取的介面是否支援了,例如outlook是否支援。經過測試,outlook 2010 以前的版本,均只支援讀取big5的編碼格式,而outlook 2010 則只支援使用unicode編碼。因此FCKEditor編輯器產生的MailTo連結,在使用outlook 2010開啟時,十分正常,但其他之前版本的outlook則全部變成亂碼。
因此有了今天這篇文章,如何在FCKEditor自訂,讓MailTo改使用Big5編碼。時做的步驟如下:

  1. 我們要先新增兩個aspx的頁面,用於接收client的資訊,在Server端將字串用Big5編碼格式做URLEncode與URLDecode後回傳。
    新增一個頁面FCKbig5encode.aspx,用於將字串做URLEncode。
    <%@ Page Language="C#" %>
    
    <% 
        if (Request.QueryString["data"] != null)
        {
            try
            {
                string data = HttpUtility.UrlDecode(Request.QueryString["data"]);
                string big5encode = HttpUtility.UrlEncode(data, Encoding.GetEncoding("Big5"));
                Response.Write(big5encode);
            }
            catch
            {
                Response.Write(Request.QueryString["data"]);
            }
        }
        else
        {
            Response.Write(Request.QueryString["data"]);
        }           
    %>
    新增第二個頁面FCKbig5decode.aspx,用於將字串做URLDecode。
    <%@ Page Language="C#" %>
    
    <% 
        if (Request.QueryString["data"] != null)
        {
            try
            {            
                string data = Request.QueryString["data"];
                string big5encode = HttpUtility.UrlDecode(data, Encoding.GetEncoding("Big5"));
                Response.Write(big5encode);
            }
            catch
            {
                Response.Write(Request.QueryString["data"]);
            }
        }
        else
        {
            Response.Write(Request.QueryString["data"]);
        }           
    %>
    將以上兩個檔案,新增於路徑 fckeditor\editor\dialog\fck_link\ 下。
  2. 再找到 fckeditor 處理 link 相關的 js 檔,fck_link.js。(我使用的版本2.6.5,路徑於fckeditor\editor\dialog\fck_link\fck_link.js ,如與您使用的版本,或路徑不相同,再自行對應變更路徑與新增頁面。)
  3. 開啟 fck_link.js 後,插入下方兩段Javascirpt ,使用此兩段Javascript,讓Client 端 Javascript 可直接呼叫,將字串做 big5 的 URLEncode。
    第一段用來與Server端FCKbig5encode.aspx頁面互動,做字串的Encode 
    function Big5encodeURIComponent(str) {
        var xml = new ActiveXObject("MSXML2.XMLHTTP");
        var data = encodeURIComponent(str);
        xml.open("get", "fck_link/FCKbig5encode.aspx?data=" + data, false);
        xml.send();
        return xml.responseText;
    }
    第二段用來與Server端FCKbig5decode.aspx頁面互動,做字串的Decode
    function Big5decodeURIComponent(str) {
        var xml = new ActiveXObject("MSXML2.XMLHTTP");
        var data = encodeURIComponent(str);
        xml.open("get", "fck_link/FCKbig5decode.aspx?data=" + data, false);
        xml.send();
        return xml.responseText;
    }
  4. 接下來將 fck_link.js 中 MailTo 相關部分,原來使用 encodeURIComponent 方法的部分,全部替換成 big5encodeURIComponent,以此類推,也將相關的decodeURIComponent 方法的部分,全部替換成 big5decodeURIComponent。這樣就完成讓FCKEditor使用big5編碼做URLEncode囉~
不過以下幾點要特別小心注意:
  1. 因為使用的是Big5編碼格式,所以要小心一些難字會變成問號(?),例如;堃。
  2. 在要編碼的內文中,要特別注意是否有(),這兩個符號。這兩個符號在Javascript encodeURIComponent方法中,會被排除不做URLEncode,但因這裡是使用Xml.open將資訊送回Server端做處理,當送回的Querystring中有(),這兩個符號。會發生錯誤,因此要小心不可有這兩個字元。如要使用,可使用全形的括弧,即可避免這個錯誤。
  3. URL有最大長度的限制,上Google查到的資訊是最大長度限制為2083個字元,但我測試得結果是2031個字元,但要小心有些字元可能在產稱mailto的url時,會再被編碼成HtmlEncode,例如&字元,會被HtmlEncode為&amp;,所以在最後呈現在Html上的字數限制計算上,要十分注意。不然會有無法開啟mailto、或有錯誤訊息的狀況發生。
以上分享給大家~

---------------------------------------------------------------------------------------------------------------------

[2010/07/22]最新訊息,上方有提到,outlook 2010已改 mailto 使用 utf-8 編碼格式。這是說法是錯誤的,說明如下:

正確來說,應該是在新版本的IE8中(不太確定是否是IE8、或更早版本、或其實在系統中亦可設定?!),加入了一個選項,截圖如下:

擷取

這個選項便影響整體OS中,所有由瀏覽器送出 mailto 連結給 outlook 時所使用的編碼方式!

Javascript URLEncode - escape , encodeURI , encodeURIComponent 的差異

在使用Javascript的URL encode時,常不清楚該使用哪一種方式,
今將escape、encodeURI、encodeURIComponent三種方法得差異整理如下:

參考幾篇不錯的文章:

  1. 清楚解釋各encode對中文的編碼方式:用Javascript替中文轉碼:escape, encodeURI, encodeURIComponent 的比較
  2. https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Functions/encodeURI
  3. https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Functions/encodeURIComponent
  4. http://blog.miniasp.com/?tag=/encodeuri
  5. http://diary.tw/march/category/Javascript

並依得到的資訊,實際測試字串"A Z a z 0 1 堃 - _ . ! ~ * ' ( ) ; , / ? : @ & = + $ #"等字元,在被不同JavaScript URLEncode方法Encode後的結果,整理如下表:

文字類型 英文 數字 中文 Unescaped characters Reserved characters Score
原始字串 A Z a z 0 1 - _ . ! ~ * ' ( ) ; , / ? : @ & = + $ #
escape後 A Z a z 0 1 %u5803 - _ . %21 %7E * %27 %28 %29 %3B %2C / %3F %3A @ %26 %3D + %24 %23
encodeURI後 A Z a z 0 1 %E5%A0%83 - _ . ! ~ * ' ( ) ; , / ? : @ & = + $ #
encodeURI
Component後
A Z a z 0 1 %E5%A0%83 - _ . ! ~ * ' ( ) %3B %2C %2F %3F %3A %40 %26 %3D %2B %24 %23

ps. 上表紅色字體表示部分,是突顯各Encode方法,不會做Encode的字元!

由上方的資訊可以整理出一些結論:

  1. 英文字數字-_.* 這些字不管是哪一種Javascript URLEncode方式,都是不會被encode的!
  2. 各Encode方法,都是Encode為Unicode,但escape是Encode為UTF-16、而encodeURI與encodeURIComponent則是UTF-8
  3. 因為 Javascript 都是 Encode 為 Unicode ,因此如有特殊用途須使用Big5編碼,需自行想辦法處理,例如 URI 中的 MailTo: 用法,outlook2010以前的版本,都只支援讀取Big5編碼! 但outlook 2010 卻又只支援讀取 Unicode @@。
  4. 符號部分,UTF-8與UTF-16的結果相同,因此上表可看到,除了被排除不Encode的字元外,使用escape與encodeURIComponent做Encode後的結果是相同的!
  5. 中文字部分,因 UTF-16 與 UTF-8 的編碼結果不同(可參考上表差異),所以如內容有中文,則必須慎選Encode的方式,不然就要有對應的處理方式!
  6. encodeURI 與 encodeURIComponent 的差異是,encodeURI 會排除對 URL 有特殊意義的字元不做編碼,因此會排除 Reserved characters 與 Score 類型的字元。
  7. encodeURI 與 encodeURIComponent 均會排除 Unescaped characters 類型的字元。

所以在使用時,我認為可由兩方面去思考,判斷應使用哪一種Encode:

  1. 您要Encode的內容,適合使用哪一種編碼方式?! UTF-8 還是 UTF-16 ?!
    (這點跟使用的環境支援哪一種Encode … 等會有相關。)
  2. 您要Encode的內容,是否包含了於 URI 有特殊意義的字元?!
大致上這三種 javascript 的 URLEncode 方式特性整理如上。 希望下次使用時,可以清楚分辨該使用哪一種囉~~~

如何在64位元作業系統中,指定Web應用程式用32位元模式執行

今天專案將Web應用程式部署至64位元的作業系統時,
果不其然的發生了問題,有支程式用 Microsoft.Jet.OLEDB.4.0 Provider 把Excel資料讀進來。
但在64位元的環境執行時,這段程式出了問題。
上Google一查,原來是 Microsoft.Jet.OLEDB.4.0 Provider 沒有For 64bit的版本。
查到的方法,就唯獨讓Web應用程式使用32bit mode一途,可解決此問題了。

在此情況下,以下介紹兩種可以讓Web應用程式使用32bit mode執行的方式!

  1. 在專案的屬性視窗中,選到建置的設定視窗,將平台目標(PlatformTarget)修改為x86即可。
    擷取1
  2. 直接修改佈署Web應用程式的應用程式集區(ApplicationPool),指定以32bit mode執行。
    (在寫此文章時,查看 IIS7.0 與 IIS7.5 兩版本,均有此選項可做調整)

    擷取 
    以上兩種方式,均可指定應用程式使用32bit 模式執行。

但如使用第一種方式,須注意到,因預設使用AnyCPU的選項,會依您佈署作業系統環境,
而對應使用不同的CPU mode。

所以當所有Library都設定為AnyCPU,僅有其中一個Library被修改指定使用x86模式時,
當佈署於x86的作業系統環境,應用程式全部都會使用x86運行,便可完全正常運作。
但當佈署至x64的作業系統環境時,便會有些以x64運行,有些要以x86運行,便會發生無法載入的錯誤情況。
因此要相當注意,有參考到的Library都必須一併指定為x86 mode,
不然應用程式在Runtime時,會發生x64無法跟x86溝通的問題。

但這問題就來了,如果是我們自己開發的程式,指定運行的Mode當然沒問題。
但如果是使用一些Third party的Tool,這時就很難保證他會用什麼模式運行了。

所以總結,是比較建議使用上方介紹的第二種做法,直接指定整體環境(在Web環境是ApplicationPool)使用x86運行,
應該會是比較保險的做法。

幫FCKEditor新增MSN小圖示

擷取 

  1. 開啟FCKEditor設定檔fckconfig.js
  2. 找到設定檔中,小圖示的設定處FCKConfig.SmileyImages,加入要新增圖示的檔名,如上範例8.gif
  3. 將新增的圖示放入FCKEditor模組目錄中,fckeditor\editor\images\smiley\msn\

依照上圖步驟,就可以輕易完成小圖示的新增囉~
可看到圖中步驟4.在FCKEditor功能中,便可看到新增的圖示囉~~

Sql 2008 新增資料表修改保護機制

有時候,當專案有需求,希望可以在資料表中增加一個欄位。

當新增的欄位,或異動,需要重建資料表,才有辦法正確變更成功的話。

在Sql 2008 便會得到如下的訊息,提醒您的異動因為需要drop 再 re-create 資料表。

此異動在預設是不允許的,我想,也許這是要保護資料不會不小心被刪掉。

擷取

可是當我們是專案剛開始在設計資料表時,資料表內還沒有任何資料。

應該是可以異動,不會有風險的。那該怎麼辦呢?!

仔細看於上圖的訊息中,有提到一個新增的選項,

The Option Prevent saving changes that require the table to be re-created.

在新版的sql2008中,增加了這個選項的防護。確保資料不會不小心被刪除了。

 

但當我們真的需要直接重建資料表,

我們可以再以下路徑找到這個設定:

Option → Designer → Table and DataBase Designers → Prevent saving changes that require table re-creation.

擷取2

預設這個選項是打勾的,表示需要啟用此保護機制。

在這邊只要將此選項勾選掉,即可直接儲存需Re-creation資料表的異動了。

但我想,異動完還是必須記得將此選項修改回啟用,

這選項應可有效確保資料不會因不小心異動資料表而被刪除!!!

Entity Framework 4.0 與 2.0 發現的差異?!

這裡的測試使用環境為Vistual Studio 2010 ,因此可分別建立.net 3.5 使用EF2.0 ,與.net 4.0使用EF4.0的專案來做比較。相信可以更容易感受到此功能的差異。

在開始前,先建立關聯的資料表,關聯圖如下:

擷取3

這裡有兩個多對多的資料表,分別為Block與Items,而這兩個資料表於Entity Framework 中的Model圖如下:

擷取1

因為BlockItems是兩個Table的關聯資料表,因此會直接在Model圖中,對應多對多關係。

在建立Entity Framework 時可選擇的選項畫面如下。

VS2008 .Net3.5設定畫面:

擷取6

VS2010 .Net3.5設定畫面:

擷取4 

VS2010 .Net4.0 設定畫面:

擷取5

接著實際寫一段code將Block逐筆寫出,並且於Block下逐筆寫出其包含之Items,

static void Main(string[] args)
{
  Entities context = new Entities();
  var q = from a in context.Block
          select a;
  foreach (var block in q)
  {
    Console.WriteLine("取區塊名稱:" + block.BlockName);
    foreach (var item in block.Items)
    {
      Console.WriteLine("---選購項目:" + item.Name);
    }
  }
}

寫出結果如下:

vs2010 .net3.5 輸出結果:

擷取7

vs2010 .net 4.0 輸出結果:

擷取8

這邊可以看出結果的差異!!!!!

為什麼會有這樣的差異呢?!

底下Debug,看一下分別在不同Framework 下,可取到的Items 資料的差異。

vs2010 .net3.5  Items內容數:

擷取0

vs2010 .net 4.0 Items內容數:

擷取

可以看到,在Entity Framework 4.0 當我們用LINQ to Entity 取到Block 時,

便同時已經取到跟他相關聯的所有Items 了,可是在Entity Framework 2.0,這是沒辦法做到的。

因此於EF4.0中,更加貼近我們是在操做Entity了!

原因為何我還不清楚,原以為是新增的 Include foreign key columns in the model 功能影響。

但經過測試,於EF4.0建立Model時,故意不勾選此選項,結果EF4.0依然可正確的抓到Items 值。

先將此問題做紀錄,待有空再來研究原因為何。