1. 程式人生 > >Asp.Net Mvc3在Mono中部署的兩個問題

Asp.Net Mvc3在Mono中部署的兩個問題

    在嘗試把MVC3專案部署在mono(2.10)上時,發現兩個問題,一個是MVC3所有Action中來自ModelBinder的實體都為null,另一個是Lucene.Net遭遇“UNC paths should be of the form \\server\share”錯誤。

    對於問題1,經過實驗,發現mono下只要是post請求,就無法通過Request獲取值,因為Request.Form.Keys.Count總是為0,拋開apache直接執行xsp4也存在同樣的問題,由於MVC版HttpContext的獲取在MVC3的相關類庫中進行,而System.Web.Mvc是私有部署的,所以問題要麼發生在mono的System.Web的實現中,要麼發生在XSP中,經過了痛苦的搜尋,有人提到mono中不能使用DefaultModelBinder,也有人提到mono當前還不足以完全支援MVC3,但如果HttpContext中根本就沒有初始化POST請求的資料,無論誰的ModelBinder都無法拼出一個Model來。後來,終於在mono的BUG更正列表中發現了一些蛛絲馬跡,在mono 2.10.2的

Release notes頁,BUG683339提到:

683339: POST variables are not transferred to HttpContext.Request.Params nor FormCollection in MVC3 app

    怪不得,mono2.10.2之前的版本中,POST資料都無法在MVC3中讀取,在更新了mono2.10.2後,ModelBinder果然正常工作。

    對於問題2,則是windows和linux下路徑的"\"和"/"的差異引起的IO異常,其實從windows環境下遷移到linux+mono中時,有80%的問題都集中在URL大小寫和windows/linux的路徑問題上。這個異常向上追蹤可在Stack Trace中看到這樣一條資訊:

at PanGu.Dict.WordDictionary.LoadFromBinFile (string,string&) <IL 0x00014, 0x00089>

    推測是盤古分詞在讀取詞典時的路徑中使用了硬編碼的路徑分隔符,通過Reflector定位到該方法,果然看到了這樣的程式碼:

public string GetDictionaryPath()
{
string dictionaryPath = this.DictionaryPath;
string currentDirectory = Directory.GetCurrentDirectory();
Directory.SetCurrentDirectory(Path.GetAssemblyPath());
dictionaryPath = Path.GetFullPath(dictionaryPath);
Directory.SetCurrentDirectory(currentDirectory);
return
Path.AppendDivision(dictionaryPath, '\\'); //<----------此處使用了硬編碼的路徑分隔符
}

    於是下載了盤古分詞的原始碼,更改其中的詞典路徑為從配置檔案中讀取,重新編輯部署了Pangu.dll後,果然可以正常搜尋。這也教訓我們,應該養成良好習慣,儘可能少地使用硬編碼,多考慮程式碼在多環境下的適用性。

    以上是使用mono的點滴Debug經驗,可能有很多人也會遇到同樣的問題,希望有所幫助。