[Resources] 讀寫 Resource

在 ASP.NET 中讀取 Resource 是再容易不過的事情了。我們只需要先加入一個 Resource 檔案(在 ASP.NET 中它會放在 ~/App_GlobalResources 資料夾之下),加入一個字串(例如 String1),然後再很簡單的使用以下程式...

 

在 ASP.NET 中讀取 Resource 是再容易不過的事情了。我們只需要先加入一個 Resource 檔案(在 ASP.NET 中它會放在 ~/App_GlobalResources 資料夾之下),加入一個字串(例如 String1),然後再很簡單的使用以下程式:

(C#)

string res = Resources.Resource.String1;

 

就可以輕易的取得資源檔中定義的字串內容。

但是,如果你想加入或寫入上述字串的內容,該怎麼做呢?你可以有兩個選擇,第一個,就是回到 Visual Studio 裡面,直接把 Resource 檔案開起來,然後編輯。你也可以寫程式去編輯這個 Resource 檔案。因為它是一個 XML 文字檔,所以寫這個程式應該也不會太難。

但不管如何,難道沒有更簡單的辦法了嗎?

其實我不曉得什麼原因,讓微軟實作了 Resources.Resource 類別,卻讓它僅有唯讀屬性,使得我們可以很方便的讀取,卻無法很方便的寫入。

如果你希望以更簡單的方法來寫入資源檔,你可以使用 System.Resources.ResXResourceWriter 類別的 AddResource 方法。這個類別和 System.Resources.ResourceWriter 一樣實作了 IResourceWriter 介面,所以都有 AddResource 方法可以使用。

你可能會問,為什麼不使用 ResourceWriter 類別來做寫入動作而非得使用 ResXResourceWriter 類別不可?其實你不妨自己試看看到底有什麼不同,可是結果恐怕會讓你吃上一驚。因為如果你使用 ResourceWriter 類別寫入資源檔,它會寫入一個二進位檔案,而且會直接把同檔名的檔案覆蓋,不會因為有同檔名的檔案存在而有任何遲疑。我已經因此而被吃掉一些資料了,所以如果你真的要試的話,別怪我沒事先警告過你。

可是當你要使用 ResXResourceWriter 類別時,你會再吃上一驚,因為你從 Intellisense 找不到這個類別。為什麼呢?因為這個類別被包在 system.windows.forms.dll 組件裡面(別問我為什麼;我也不知道),而 ASP.NET 預設是不會自動載入這個組件的,你必須以手動方式把 System.Windows.Forms 組件加入專案的參考裡面,然後才可以匯入這個類別。

最後的範例程式如下:

(C#) 

using System.Resources;
...
ResXResourceWriter writer = new ResXResourceWriter(HttpContext.Current.Server.MapPath("~/App_GlobalResources/Res1.resx"));
ResXResourceReader reader = new ResXResourceReader(HttpContext.Current.Server.MapPath("~/App_GlobalResources/Res1.resx"));
foreach (DictionaryEntry dic in reader)
    writer.AddResource(dic.Key.ToString(), dic.Value.ToString());
writer.AddResource("String1", "ABCDE");
writer.Close();
reader.Close();

先用 ResXResourceReader 把原始資料讀進來,再使用 AddResource 方法把資源項目加入 ResXResourceWriter。如果相同名稱已經存在,就會把值覆蓋上去。此外,記得兩個 Close() 方法一定要呼叫。

後記: 請別問我為什麼既然已經寫了「讀寫資源檔範例」, 又寫了「[Resources] 讀寫 Resource 」。老實說, 我也不記得了 (這兩篇都已經是很久以前寫的了)。不管如何, 兩種做法顯然很不一樣, 而我現在也懶得去驗證這兩種做法有沒有什麼不對、或者哪一種比較好。如果讀者有什麼看法, 歡迎給我意見。


Dev 2Share @ 點部落