從.NET到Mono-記Kooboo CMS對Mono的相容歷程:二、大小寫敏感問題,到處都是地雷
在Linux/Unix系統中,對任何檔案路徑,檔名,URL地址的處理都是大小寫敏感。對於這點設計,讓我們長期從事基於Windows平臺開發和工作的開發人員情何以堪啊。儘管可能這樣設計是有它的特殊目的和出發點,但我直到現在仍然認為這點是一個非常蛋疼的設計。我試圖找到一些理由來解釋Linux為什麼處理這些字串使用大小寫敏感,但是得到的答案都是一些無關痛癢的理由:
- 大小寫敏感後,可以用更短的檔名來表示更多的檔案。比如a.txt和A.txt它們是不是一樣的檔案,但是大小寫不敏感後,它們只能表示同一個檔案。
- 大小寫敏感,讓字串(檔名)更容易排序。
- Linux是用C語言寫的,在C語言裡面,字串是大小寫敏感的。難道C++,C#不是大小寫敏感?
- 大寫和小寫字元,本身它們的ASCII值就不一樣,本來就應該認為它們是不一樣的字元?
上面的這些討論,難道有一個理由可以成為大小寫敏感後所帶來的不便的替罪羊(請允許我以一個Windows使用者的角度來評論這個設計)?在我這段時間的跨平臺研究經驗中,這個問題已經不再是方不方便的問題了,已經上升到軟體相容層面上的很大問題。你可以說,這是我們自己寫程式的的隨意性造成的。但是對於長期基於Windows平臺開發的開發人員,又有多少程式設計師會注意到檔案路徑和檔名的大小寫統一問題。在我所遇到的問題中,至少80%以上是由於檔名和路徑大小寫的不一致所導致的,而這些問題,有時候也是相當長的時間來進行除錯後才會察覺出來。下面就來看看,我到目前為止,發現的由大小寫敏感所帶來的軟體的相容問題吧:
- 首頁一開啟,你會發現出現一個404錯誤。如果運氣好的話,那你檢查一下是不是把Index.aspx寫成index.aspx。
- 當你把頁面開啟之後,你發現怎麼頁面的樣式都亂七八糟的,根本就不是我們正常的顯示效果。那我們可能要藉助一下Firebug或是其它的HTTP網路請求檢視工具來看一下是不是有哪些樣式的請求出錯了,是不是把L寫成l了。
- 當你把樣式的問題也解決了以後,你可能還會有很多圖片,logo沒有辦法正常顯示。如果在Windows下面訪問正常的話,那你的第一個反應也是應該檢查一下大小寫問題。
- 同樣的問題,還會出現在請求指令碼檔案中。
- 如果你的程式中,有做檔案讀寫操作的話,80%是可能會執行不正常的,同樣是因為你的檔名(路徑)大小寫不一致引起的,要重點檢查。
- 我們使用MVC,最經常的都是URL,controller,View的名稱會是以一種約定的形式存在,並且VS提供了一個很好的腳手架,讓我們可以確保Controller和View的大小寫基本都能保持一致,但這樣就夠了嗎?在這種請求中,你也許會經常收到各種View無法找到的異常,第一個反應,你就是應該要檢查一下檔案和路徑的大小問題了。但是要解決這個問題,卻不是通過修改程式就能解決的。假設有AccountController這個View,在Windows平臺下,我們通過account或是Account都可以正常請求,但在Linux下,你通過account是不能正常請求的。不能正常請求,不是因為Controller無法正常處理,因為MVC中,本身對查詢controller已經是大小寫不敏感了。但是由於你是用account來請求的,那麼它此時認為的controllerName是account,它會以account這個字串去找相應的View,假定我們原本的View是Account,那此時它一定是會找錯的。這個問題,基本沒有什麼好辦法,要麼從底層的IOMAP來解決,要麼就是強制要求URL也大小寫敏感。
- 同樣在MVC中,有一個Metadata,叫做UIHit,它可以用來指定某個欄位對應的編輯模板的。在這裡,我們假設使用了UIHit("password"),但是在EditorTemplates中,存在Password.cshtml,同樣的讓我們的頁面產生一些CSS相容性問題的錯覺。
還好,CSS,Javascript的語法都大小寫敏感的,要不然痛苦還會多很多。
以上提到的這些大小寫的問題,Mono團隊也很早就意識到如果不解決,可能會是Mono更好發展的一個障礙。因此他們提供了一項叫做IOMap的底層對映來遮蔽由檔案路徑大小不同所帶來了相容性問題。但是,在介紹中,只是提及對基於Apache的配置例子,也許也有針對XSP的支援例子:
MONO_OPTIONS="--debug --profile=iomap" xsp2
但是由於我需要在MonoDevelop中除錯更多的其它問題,因此我也需要在MonoDevelop用XSP啟動站點除錯時開啟IOMap的選項,可惜,至今我還沒有設定的辦法。今晚,我看到了Mono Tools for Visual Studio 2.0 Beta 1除錯可以配置這個選項,但為何這個Mono_Tools也可以跨平臺呢?莫非它不僅僅是一個Visual Studio的外掛?也許奧祕就在這裡。希望過幾天我就可以解決除錯時使用IOMap的問題。這樣真的可以減少太多的程式碼改動了
本文結束