標籤:class blog c code java ext
因為另有開發記錄工具最新沒怎麼在 cnblog 寫開發備忘.不過我覺得這個是個比較嚴重的問題,覺得有必要讓更多的人知道處理方法,所以在 cnblog 也放上一篇希望廣為傳播.
--------------------------------------------------
第一次修改
--------------------------------------------------
NVelocity 這個工具的使用相信大多數網友都是因為和我一樣在 java 時使用的是 Velocity ,因此在使用 C# 特別希望有一個類似的工具包.而搜尋得到的就是 NVelocity.
NVelocity 兩三年前我是用過的,所以並不覺得這次用會有什麼問題. 照例在網上搜尋後加入工程及網上的各種樣本就點運行.為料出現了 "It appears that no class was specified as the ResourceManager..." ,心裡也並不慌張,因為根據經驗估計也就是某個 dll 引用沒弄進來. 結果折騰了各種檔案和網上的各種例子就是不對. 不知不覺一個上午就過去了,覺得事情有點嚴重,放下大意的心情,開啟了我以前的工程.發現有幾個不同的地方:
1.之前公司用的是 vs2010 , 現在用的是 vs2008,沒辦法直接編譯.
2.之前工程中只有一個 NVelocity.DLL 檔案,也沒有源碼,而這次下載的卻有 NVelocity.dll,NVelocity.http.dll 及源碼等多個檔案.
好吧,我把這個 NVelocity.dll 替換好了.但編譯時間即報錯,查看了檔案的版本資訊,其寫明了是 for .net 4.0 的,當然這時直接換用 vs2010 就好了.不過我的情況稍微特殊,生產環境是 .net 2.0 的,不是太方便讓人升級,再說升級 .net 環境有時候會成為災難 -- 我以前升級 .net 3.5 時碰到過很多次,雖然 .net 4.0 好很多.實在不想節外生枝.
好吧,又在網上搜尋了無數的類似問題.都不行.期間看到說因為 NVelocity 交由了什麼 xxx 維護了,所以 NVelocity 的源碼版本有多個. 這時意外在某網友的例子中發現了能用的 .net 2.0 版本 NVelocity.dll 但其檔案沒有版本資訊,顯然不是官方的,但這位網友的文章顯示是多次轉載已經找不到其如何修改的資訊了.我下載的檔案位於(NVelocity-0.4.2.8580):
http://nvelocity.sourceforge.net/
因為這是 google 搜尋的第一個,而 baidu 搜尋的第一個就是那個 for .net 4.0 版本的:
http://nvelocity.codeplex.com/
而網友那個可用的 .net 2.0 版本已經沒有了.說實話我理解不了 sourceforge.net 這個為什麼用不了,這麼有名的控制項在這麼有名的網站上提供的檔案居然是錯誤的.通過我搜尋的其他資訊,相應的 bug 應當是有人提交了的,不知為什麼沒有提交到 sourceforge.net 這裡.
好了,不管那麼多,至少在我的中文版本 vs2008 上需要修改以下部分才能正常使用:
檔案 ResourceLocator.cs 中
try
{//clq
foreach (Assembly a in assemblies)
{
String prefix = a.FullName.Substring(0, a.FullName.IndexOf(",")).ToLower();
String[] names = a.GetManifestResourceNames();
try
{//clq //這裡都沒錯,應當是前面的兩句話造成的
foreach (String s in names)
{
if (s.ToLower().Equals(fn) || s.ToLower().Equals(prefix + "." + fn))
{
this.filename = s;
assembly = a;
isResource = true;
}
}
}
catch (System.Exception ex)
{
String s = ex.Message;
System.Console.WriteLine("bbbbbb:" + s);
}//clq
}
}catch(System.Exception ex)
{
String s = ex.Message;
System.Console.WriteLine("aaaaaa:" + s);
}//clq
}//if clq
根據我的測試大概的出錯原因是,某個資源檔在反射機制搜尋時不支援某個介面,導致其異常退出了剩餘資源的處理.所以直接加幾個 try 就行了(ps:反射實現,恐怕效率不高吧).
這樣修正後下面這樣的代碼就可以通過運行了.
VelocityEngine vltEngine = new VelocityEngine();
//4.0 這裡是 RuntimeConstants.RESOURCE_LOADER
vltEngine.SetProperty(RuntimeConstants_Fields.RESOURCE_LOADER, "file");
string path = _this.Server.MapPath("~/");
vltEngine.SetProperty(RuntimeConstants_Fields.FILE_RESOURCE_LOADER_PATH, path);
vltEngine.Init();//不修改庫代碼,這裡會報錯
--------------------------------------------------
第二處修改
--------------------------------------------------
以上修改後使用一段時間後,因為我個人的工具鏈中很多是不支援 utf8 的(或者很麻煩),在此將模板改為了普通的 gbk 編碼方式.這時發現這個版本沒法糾正編碼形式.我修改了一個地方才行.正常的編碼糾正代碼為:
vltEngine.SetProperty(RuntimeConstants_Fields.OUTPUT_ENCODING, "GB2312");//修改 NVelocity-0.4.2.8580 的源碼後才能用這兩個,並且最好是用 GBK
vltEngine.SetProperty(RuntimeConstants_Fields.INPUT_ENCODING, "GB2312");//
在此版本 nvelocity 中不起作用,需要修改:
Template.cs 檔案中
//System.IO.StreamReader br = new System.IO.StreamReader(new System.IO.StreamReader(is_Renamed, System.Text.Encoding.GetEncoding(encoding)).BaseStream);
System.IO.StreamReader br = new System.IO.StreamReader(new System.IO.StreamReader(is_Renamed, System.Text.Encoding.GetEncoding(encoding)).BaseStream, System.Text.Encoding.GetEncoding(encoding));//clq 2014.05.23
很顯然作者可能是老外,編碼指定的位置弄錯了.
--------------------------------------------------
為方便大家參考,我放上修改後的全部專案檔,這裡用的是 debug 版本,對效率有要求的環境請自動編譯其他版本.代碼修改的地方不多,大家可全文檢索搜尋 "//clq" 字樣就能找到,其他代碼因為本人水平有限也看不懂也不敢亂改.出於穩定和不想惹麻煩的原因未來也不打算大改,能在我目前這個小項目中用就行.
為:
http://files.cnblogs.com/-clq/NVelocity-0.4.2.8580%5B2014.05.23%5D%5Bclq_modify%5D.zip
--------------------------------------------------
如果還有其他 bug 我會再上傳新版本.另外也希望有瞭解內情的網友介紹下 nvelocity 如此混亂的原因.