Linux.NET學習手記(6)
各位讀者大家好,好長一段時間沒有更新文章了,自從參加工作之後,每天等待去做的工作沒完沒了,個人的時間也變得奢侈起來,今後要儘量從中脫身,抽更多的時間來完成自己想做的事情(希望如此)。
言歸正傳,上一回合中,我們討論學習瞭如何在Linux.NET中讓一個 MVC 3.0 和 MVC 4.0 的專案在mono中跑起來。而就在早前幾天,我在新浪微博中看到一位朋友轉發了一篇有關如何將MVC4.0專案升級到MVC5.0的文章:《How to Upgrade an ASP.NET MVC 4 and Web API Project to ASP.NET MVC 5 and Web API 2》。我不禁感嘆,這時代的步伐還真快,MVC還真的一年一版本的出,同時,一個想法在腦海中形成:既然MVC都發展到5.0了,那當前能否讓它在Mono中跑起來呢?
進入本回合主題,本回閤中我們將討論學習:
1、得到一個ASP.NET MVC 5 的框架應用
2、將一個簡單的ASP.NET MVC 5 的應用部署到Linux中
本回合的程式原始碼包,可以點選“這裡”進行下載。
1、得到一個ASP.NET MVC 5 的框架應用
巧婦難為無米之炊,想要部署一個MVC 5的應用,必須先得到一個基於這個版本的MVC應用。當前我使用的開發工具是Visual Studio 2012,而ASP.NET MVC 5.0 卻是跟 Visual Studio 2013 繫結一同釋出,官方貌似還沒有提供獨立的模板安裝檔案。當然,我們也不可能為了做這麼一個ASP.NET MVC 5.0的實驗而跑去下載並安裝一個Visual Studio 2013,因此我們要通過一些其他辦法來獲得這麼一個應用。
NuGet,果然是一枚好東西,我們很容易的就在上面的發現了ASP.NET MVC 5.0 的包,這樣,我們可以先使用Visual Studio建立一個MVC 4.0(或以下)的專案,然後在通過NuGet為該專案升級即可。
首先,我們先建一個ASP.NET MVC 4.0 的專案:
然後調出我們的控制檯程式(具體可以在:“工具->庫程式包管理器->程式包管理器控制檯”調出),輸入:“Update-Package”,讓它自動的把所有當前的版本庫升級。
第三步,我們需要對“~/View/Web.config”中的配置進行修改。
具體的修改內容,可以參照前言中說提及的那篇文章,“Update the web.config files under the Views folder”這一節中的1、2兩個步驟,在這裡,我把我修改後的Web.Config配置全部貼出來讓各位讀者參考。
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" /> <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" /> </sectionGroup> </configSections> <system.web.webPages.razor> <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <pages pageBaseType="System.Web.Mvc.WebViewPage"> <namespaces> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Routing" /> </namespaces> </pages> </system.web.webPages.razor> <appSettings> <add key="webpages:Enabled" value="false" /> </appSettings> <system.web> <httpHandlers> <add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/> </httpHandlers> <!-- 在檢視頁面中啟用請求驗證將導致驗證在 控制器已對輸入進行處理後發生。預設情況下, MVC 在控制器處理輸入前執行請求驗證。 若要更改此行為,請對控制器或操作 應用 ValidateInputAttribute。 --> <pages validateRequest="false" pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> <controls> <add assembly="System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" /> </controls> </pages> </system.web> <system.webServer> <validation validateIntegratedModeConfiguration="false" /> <handlers> <remove name="BlockViewHandler"/> <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" /> </handlers> </system.webServer> </configuration>Web.Config
最後,我們再建立一個簡單的控制器和頁面,然後把它跑起來。
在這裡,我有幾點本小節的小建議或解析:
1、在建立初始專案的時候,建議選擇MVC專案,而非WebForm應用程式。為什麼呢?這裡並不是說通過WebForm+MVC庫的方式無法實現,而是如果各位讀者採用WebForm+MVC庫的方式實現的話,除了沒有辦法使用Visual Studio所提供的便利之外,建立的每一個View頁面,後方都有可能帶一個CS檔案(如果你是通過建立aspx頁面然後改字尾名之類的),並且編譯釋出之後的程式碼,View中的內容也有可能被編進了dll中。總而言之,這都將造成極大的不便。
2、由於ASP.NET MVC 5僅支援.NET FrameWork 4.5以上的版本,因此新建專案是,FrameWork 4.0 或 以下的版本是無法升級到MVC 5 的。
3、使用NuGet升級,因為本次"Update-Package"沒有帶上任何的引數,因此係統會預設的幫你升級到最新的版本,換句話說,如果下次是MVC 6 的話,NuGet則會幫你升到最新版本(當然,是否成功則是另外一個問題啦)。各位讀者也可以通過在專案資源管理器中“右鍵本專案->管理NuGet程式包”來對這些庫進行相關操作。
2、將一個簡單的ASP.NET MVC 5 的應用部署到Linux中
好的,接下來,我們要將這個簡單的小專案部署進Linux當中,由於使用的是.NET FrameWork 4.5,我手頭上的mono版本擔心會有所不足(原先版本為:mono 3.0.12)因此我把Linux中的Mono重新安裝了一遍(說起慚愧,由於“rm -rf /usr/local/mono/” 時忘了關Jexus,重新編譯的時候還Error了一次),現在的版本為:mono 3.2.3。
把環境搭建好之後,再把這個小專案釋出到Linux中(jexus網站配置和網站釋出過程這裡不再寫了,又需要的讀者可以翻閱前面的文章),然後嘗試訪問。
嗯嗯,就知道不會有這麼順利的,我們把“CustomError”設為“Off”看看它報了些什麼錯。
第一個錯誤報出來了,說是無法載入“System.Web.Http.WebHost”程式集中的一個方法。
我們先檢查是否是因為缺少程式集造成的。
檢查發現,這個程式集已經自帶在bin資料夾中,初步排除是缺少程式集造成的,並且改程式集的版本也是5.0.0.0,也排除版本問題造成的。
再觀察它是否和mono不相容(如該版本庫使用了和作業系統緊密關聯的東西之類的),在觀察之前這裡有個小技巧,那就是先看看mono中有沒有這個程式集,如果有,則把mono裡面的庫直接替換它,如果沒有再慢慢觀察。
很幸運的,找到了這一個對應的程式集,我們把它抽取出來,直接替換掉bin裡面的這個程式集。
然後再重新整理頁面:
好的,第二個問題報出來了,這次是程式集中缺少方法了。
通過名稱空間來查詢,我們尋尋覓覓的找到了bin資料夾中“System.Web.Http.dll”中的class HttpConfiguration:
雖然Methods沒有明確的寫有“get_Service”這個方法,不過留意紅色框框那裡,那裡使用了語法糖,程式集編譯後會自動的產生這個方法,因此此dll中是有這個方法存在的。
與此同時,我們發現了mono中也存在這個程式集:
我們再撬開mono中的這個程式集:
可以發現,這兩個屬性,雖然名稱相同,但是卻是分別兩個不同的型別,細心的讀者還能夠發現,就連這個類本身都是有不少東西是不同的。
這樣的話,我們就把mono的這個程式集拿來替換掉bin下的這個程式集。
再次重新整理我們的頁面:
嘿嘿,出現了。結果證明,ASP.NET MVC 5又跑起來了。
寫在本回合最後,最大的感想就是,在漫步漫長的失敗的荊棘道路之後之後,成功的終點或許就在你面前的一步,只是因為霧太大了你沒有看清而已。做這個實驗時,前一個晚上折騰到三點半都沒有結果出來,當時就放棄了,不過第二天靈感一來了,又花了幾分鐘再次嘗試,最後產生了這一篇文章。
好的,不多說,期待下一次見面。