Linux.NET學習手記(6)

各位讀者你們好,好長一段時間沒有更新文章了,自從參加工做以後,天天等待去作的工做沒完沒了,我的的時間也變得奢侈起來,從此要儘可能從中脫身,抽更多的時間來完成本身想作的事情(但願如此)。html

言歸正傳,上一回合中,咱們討論學習瞭如何在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中跑起來呢?web

進入本回合主題,本回閤中咱們將討論學習:api

  一、獲得一個ASP.NET MVC 5 的框架應用mvc

  二、將一個簡單的ASP.NET MVC 5 的應用部署到Linux中app

本回合的程序源碼包,能夠點擊「這裏」進行下載。框架


一、獲得一個ASP.NET MVC 5 的框架應用asp.net

巧婦難爲無米之炊,想要部署一個MVC 5的應用,必須先獲得一個基於這個版本的MVC應用。當前我使用的開發工具是Visual Studio 2012,而ASP.NET MVC 5.0 倒是跟 Visual Studio 2013 綁定一同發佈,官方貌似尚未提供獨立的模板安裝文件。固然,咱們也不可能爲了作這麼一個ASP.NET MVC 5.0的實驗而跑去下載並安裝一個Visual Studio 2013,所以咱們要經過一些其餘辦法來得到這麼一個應用。ide

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」這一節中的一、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

最後,咱們再創建一個簡單的控制器和頁面,而後把它跑起來。

在這裏,我有幾點本小節的小建議或解析:

  一、在創建初始項目的時候,建議選擇MVC項目,而非WebForm應用程序。爲何呢?這裏並非說經過WebForm+MVC庫的方式沒法實現,而是若是各位讀者採用WebForm+MVC庫的方式實現的話,除了沒有辦法使用Visual Studio所提供的便利以外,創建的每個View頁面,後方都有可能帶一個CS文件(若是你是經過創建aspx頁面而後改後綴名之類的),而且編譯發佈以後的代碼,View中的內容也有可能被編進了dll中。總而言之,這都將形成極大的不便。

  二、因爲ASP.NET MVC 5僅支持.NET FrameWork 4.5以上的版本,所以新建項目是,FrameWork 4.0 或 如下的版本是沒法升級到MVC 5 的。

  三、使用NuGet升級,由於本次"Update-Package"沒有帶上任何的參數,所以系統會默認的幫你升級到最新的版本,換句話說,若是下次是MVC 6 的話,NuGet則會幫你升到最新版本(固然,是否成功則是另一個問題啦)。各位讀者也能夠經過在項目資源管理器中「右鍵本項目->管理NuGet程序包」來對這些庫進行相關操做。

 

 二、將一個簡單的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又跑起來了。


寫在本回合最後,最大的感想就是,在漫步漫長的失敗的荊棘道路以後以後,成功的終點或許就在你面前的一步,只是由於霧太大了你沒有看清而已。作這個實驗時,前一個晚上折騰到三點半都沒有結果出來,當時就放棄了,不過次日靈感一來了,又花了幾分鐘再次嘗試,最後產生了這一篇文章。

好的,很少說,期待下一次見面。

相關文章
相關標籤/搜索