Linux.NET學習手記(5)


上一回合中,我們牛刀小試的在Mono中部署了我們的第一個ASP.NET應用,此外我們還結合了PostgreSQL數據庫實現了一個簡單CRUD操作的小站點。它們的成功部署並正常運行很好的體現出.NET在Linux中運作的可行性。

同時,在上回合結尾部分中提到,這回合我們將一起討論學習企業級開源框架“Spring.NET”在Mono中的部署使用。但是,最近由於個人的一些私事,一直都沒有時間對Spring.NET作出系統的學習,在這里,我向各位讀者表示歉意。因此,在本回合中,我們學習討論的內容將發生一些變化,我們不再討論“Srping.NET”如何在Mono中部署,我們轉而討論學習跟WebForm處於平行位置的“ASP.NET MVC”如何部署到我們的Mono中,示例代碼可以點擊這里下載(由於代碼過大,無法上傳到園子中,所以我放到了微盤,望各位讀者見諒)。

本回合,我們將討論學習:

1、部署前的准備工作

2、從零開始,把MVC3網站應用程序部署到Mono中

3、從部署MVC3中啟發,把MVC4部署到Mono中

4、另外一種與前面部署方式“相逆”的MVC4部署方式


1、系統約定——部署前的准備工作

最近一段時間,許多朋友都紛紛發帖發博客表示已經成功的在Mono中成功的部署了最新版的MVC框架,相當的喜聞樂見。MVC是什么,我想各位讀者一定知道,它作為微軟推出的重要建站模式,其地位與WebForm相當,重要性也是不容忽視的。試想一下,如果MVC無法在Mono中部署,那我們的Linux.NET仿佛就是一只折翼了的小鳥——“想要飛也飛不高?“不對,直接是飛不起來了。因此,MVC能夠正常的在Mono中運行似乎已經就是Linux.NET的一項”理所當然“的事情。

好的進入我們的正題,在部署MVC之前,我們需要新建一個Jexus的網站配置:

我們先在Linux中新建一個存放文件的文件夾,然后cd(進入)到Jexus存放網站配置文件的目錄,再新建一個本次實驗的網站配置文件”linux.net5“

添加上我們配置的內容

最后保存退出,然后再重啟我們的Jeuxs即可。

在這里,特別值得注意的地方:

那就是”NoFile“配置項,各位讀者一定要把此功能關閉(添加后注釋掉或直接就不添加進去,Jexus默認此功能是關閉的)。在MVC中我們的訪問路徑是經過路由重寫的,當我們發起一個訪問請求時,比如:localhost/Home/Index/,請求會經過路由的匹配並改寫,最終把請求指派到Controller文件夾中的HomeController.cs文件中的Index方法,然后再由該方法對請求作出處理並發出應答。在整套的MVC”請求--應答“處理過程中,瀏覽器在地址欄發起的URl請求在網站中未必都是真實的文件物理地址訪問請求。而這恰恰相反的,在Jexus的NoFile檢測中,Jexus會對用戶發起的訪問請求(URL)進行文件物理地址的檢測,檢測不通過時就直接對用戶應答一個預設的應答頁面(比如這里的404頁面),不再使用.NET的功能對URl作更多的處理,因此,請求將永遠無法指派到正確的Action進行處理,整套的MVC網站也會因此而報廢。

同樣,對於一些在.NET中使用URlRewrite的站點,Jexus的”NoFile“功能也是需要關閉的,原因與MVC一樣,將會被URL重寫的請求還沒有通過Jexus這一關就被拒絕了,無法繼續的進入.NET進行處理,網站的訪問也會因此而造成一定程度的影響(這里網站不會被報廢,因為在瀏覽器中輸入真實的物理地址,網站又可以正常的訪問)。

 

 2、部署MVC3網站應用程序

Mono中部署MVC3應用程序,這不是我們本回合的終極目標,但是確實本回合最重要的內容,因為只要學會了在Mono中部署MVC3,部署MVC4也就是那么一回事了。其實,在Mono中成功部署MVC3也不是一件新鮮的事情,早前就已經有不少成功的案例,園子中也有一些關於如何在Mono中部署MVC3的文章,各位讀者如有興趣,可以自行查閱,當然,讀者們也可以從本文中直接找到方法,我們在這里采用的是Step By Step的討論學習方法,一步一步的說明白如何操作,並指出當中需要注意的地方和解析原因。

好的,我們先新建一個MVC3應用程序”MVC31“,並選擇”空模板“和”Razor視圖引擎“

由於這個是一個空模板,里面沒有任何現成的Controller,我們簡單的新建一個HomeController,並添加上一個Index Action和相關的視圖。然后在windows中運行:

那是沒有問題的,但如果我們發布到Linux中,效果就不一樣了:

沒錯,正如所想的一樣,無法正常運行,按照上面的提示,我們設置”CustomError“節點,把它設置為”OFF“,重新發布,看看那里出了問題:

第一個問題出現了,很明顯,是由於Entity Framework引起的。沒錯,如果有認真讀過我前一篇文章《Linux.NET學習手記(4)》 的讀者大概已經明白其中的原因和知道解決辦法了。正如我上回合為什么沒有使用EF(我最喜歡的ORM)而改為使用PetaPoco的原因一樣,Mono中的EF版本已經是6.0並且還不支持低於此版本的EF框架,恰好微軟正式發布的EF版本最高只有5.0,於是這就造成了我們這里的第一個錯誤。不過這里的問題也只是暫時性的,隨着微軟將來EF6.0的發布,這個問題,將會得到解決。

我們通過NuGet卸載所有的Entity Framework。

然后再清除Web.Config和Global中的一些殘留項,然后再次發布。

然后順利的進入到我們的第二個問題,這里我解釋一下出現此問題的原因,由於mono 3.0.X對語言文化的支持暫時還沒有對中文支持(2.X中則可以支持中文),因此系統默認所使用的”zh-CN“讓Mono無法識別。此問題的解決辦法就是:在WebConfig的”system.web“節點中添加上”globalization“節點,並把當中的”uiCulture“設置成”en-US“。在這里我們推薦的配置為”<globalization culture="zh-CN" uiCulture="en-US"/>“,這樣就可以讓我們的程序本身以”英語“語法來運行,但是顯示時卻能夠以”中文“語法來顯示。

我們添加上這個節點,並重新發布:


非常不幸的,我們繼續進入到了一個新的錯誤,到這里,各位讀者有什么感覺了?抓狂了?想想放棄了?俗話說:”行百里者半九十“,這時千萬別放棄,因為成功就在眼前了。通過從網上翻閱大量的資料,我們找到這這次問題的真凶,沒錯,作怪的就是”Microsoft.Web.Infrastructure.dll“,我們把Windows中”Microsoft.Web.Infrastructure.dll“和Mono中的”Microsoft.Web.Infrastructure.dll“反編譯:

可以看出,Windows中的Infrastructure和Mono中的Infrastructure還不是同一回事,那這就好辦了,我們把MVC3項目中的Infrastructure剔除,讓程序使用Mono自帶的動態庫,或許就可以解決我們現有的問題。我們刪除這個動態庫后,再次發布:

終於看到了我們一直努力想要看到的”Index“,MVC3成功的在Mono中跑起來了。

 趁熱打鐵,我們再結合上PostgreSQL數據庫和PetaPoco快速的建立一個CRUD的小應用。

我們先新建一個商品表”Goods“,其表結構如下:

然后在新建相關的Controller、Model、View等,這里就不再介紹當中的代碼如何編寫和實現,有興趣的讀者可以在代碼演示中查看。

把做好的站點發布到Mono中:

頁面能夠正常顯示,沒有問題,我們在試試添加一個新的商品:

添加商品時報了一個錯,同時在“Details”中提示有一個程序集找不到。

通過排錯,我們發現了我們引用的一個DLL文件在Mono中是沒有的:

這樣,我們只要在“C:/Windows/assembly”目錄中找到“System.ComponentModel.DataAnnotations.dll”(注意版本),然后再手動的添加到我們發布的網站中的bin目錄中即可。

再次添加數據,OK!成功添加!

出現了“Linux.NET學習手記”這個商品。至此,MVC3的簡單部署已經完成~!!

這里做一些小提示:

  (1)、由於我采用了的是虛擬機,因此我結合了一個Linux的Samba服務來直接發布,各位讀者也可以采用Ftp或者發布到本地再上傳的方式進行網站的發布,發布后記得重啟一下Jexus。

  (2)、“Infrastructure”動態庫除了可以采用發布會刪除的方式進行處理,也可以采用“不復制”的屬性才處理

  (3)、讀者們也可以參考《在mono3.0.10+Jexus5.3上運行MVC4和WebApi的要點》這篇文章,上面的方法與這里有師出同門之道。

 

 3、Mono中部署MVC4

上一小節中,我們歷盡艱辛“取得真經”,成功的把一個MVC3網站應用部署到了Mono中,在這取得重要的成功之后,我們向我們本回合的終極目標繼續推進——在Mono中部署一個MVC4應用。其實,無論是MVC3還是MVC4,它們的部署方法都是類似的,我們在上小節中詳講了MVC3的部署就是為了能夠在部署MVC4起到一定的參考作用。

 好的,心動不如行動,我們馬上的新建一個MVC4的網站應用:

然后再根據我們剛才部署MVC3的經驗步驟,進行相關的修改:

  (1)、剔除所有Entity Framework的應用(使用NuGet卸載EF,並清除所有關於EF的殘留)

  (2)、在Web.Conf配置文件中的“system.web”節點中加入“<globalization culture="zh-CN" uiCulture="en-US"/>”

  (3)、移除“Infrastructure”這個動態庫文件

把這個MVC4應用程序發布到Mono中:

可以正常的運行,同樣的,我們在創建一個“商品”的增刪查改,並把缺少的“System.ComponentModel.DataAnnotations.dll”補上:

同樣的實現了我們想要的功能。

通過“照葫蘆畫瓢”的方法,我們把一個MVC4的網站應用程序順利的部署到Mono中了,其實也就差不多而已。

 

4、另一種版本的MVC4部署方法

從本回合開篇起,無論是部署MVC3還是部署MVC4,我們所采用的辦法都是直接使用Visual Studio所提供的MVC模板,然后通過“哪里不行刪哪里”的方法,把Mono中不支持或無法直接兼容的地方進行刪除或修改。可以說,我們采用了一種“逆向”的方法來獲得一個Mono支持的MVC應用。說到這里,各位讀者可能猜到,“既然有這種逆向的方法,應該也會有一種正向的辦法來部署”。近日我讀到了一篇題目名為《嘗試在 Mono 3.0 下運行 ASP.NET MVC 4》的文章,受到了一些啟發,發現還真的有讀者們所說的“正向”方法來獲得Mono支持MVC4應用程序。那就是不使用Visual Studio所提供的MVC模板,通過為Web應用程序添加必要的MVC庫文件的方式手動的搭建起一個MVC應用程序。

在本小節中,我們將嘗試的通告手動的方法,獲得一個Mono支持的MVC4網站應用程序。在參照那篇文章的同時,結合我們“逆向”部署的方法與經驗,在Mono中部署我們想要的MVC4應用程序。

首先,我們新建一個空的Web應用程序(注意,不是MVC4應用程序):

然后通過NuGet管理工具,安裝上MVC4的庫文件:

然后在手動的創建相應的文件夾和文件:

這里解析一下,有幾個文件以及文件夾是必須創建的:

  (1)、Controller文件夾:用於存放控制器

  (2)、Views文件夾:用於存放模版

  (3)、Models文件夾:用於存放實體類文件

  (4)、Global.asax文件:用於應用程序啟動時初始化(注冊路由等)

在網站配置文件中添加上MVC4需要用到的一些配置:

<configuration>

  <appSettings>
    <add key="webpages:Version" value="2.0.0.0"/>
    <add key="webpages:Enabled" value="false"/>
    <add key="PreserveLoginUrl" value="true"/>
    <add key="ClientValidationEnabled" value="true"/>
    <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
  </appSettings>
  
    <system.web>

      <globalization culture="zh-CN" uiCulture="en-US"/>
      
      <compilation debug="true" targetFramework="4.0" />
    </system.web>

</configuration>

剔除會在Mono中“作怪”的“Infrastructure”動態庫文件,然后在全局配置文件的“Application_Start ”方法中注冊上路由:

protected void Application_Start(object sender, EventArgs e)
{
   AreaRegistration.RegisterAllAreas();
   GlobalFilters.Filters.Add(new HandleErrorAttribute());
   RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

   RouteTable.Routes.MapRoute(
   name: "Default",
   url: "{controller}/{action}/{id}",
   defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
   );
}

 手動的在Controller和View中創建控制器和模板(這里不詳講,只需注意要繼承相應MVC類),然后再發布到Mono中:

Controller找不到頁面了,我們打開發布后的目錄:

我們的Views文件夾不見了。其實,這是由於我們新建的是WebForm的應用程序,發布時,我們的頁面會被嵌入到了bin目錄的程序集中,所以MVC的模版解析引擎無法在根目錄中找到VIews目錄以及里面的所有模板。這個文件的解決辦法也比較簡單,只需把Visual Studio中的Views文件夾整個的拷貝到網站根目錄中即可。

再次訪問:

OK~!!正常訪問!

這里我有一點要聲明一下,Mono的HttpRuntime是支持targetFramework的,因此我們這里並沒有把“targetFramework”去除(跟參考文章有所不同),各位要多加留意~!!


本回合中,我們嘗試性的並成功把MVC3網站應用程序部署到Mono中,並根據MVC3的部署方式推演出了MVC4的部署方式,同時還介紹了相對於我們現有部署方式的Web應用程序升級為MVC4應用程序的方式部署。希望各位讀者在通讀全文之后能夠親自的動手實現一遍,“世上無難事,只怕有心人”,只要有恆心,所有的困難最終都不是困難。同時,如果各位讀者有一些更好的部署點子或對本文有任何的看法和建議,歡迎留言分享和指正。

好的,本回合暫時就到這里了,這里我就不作下回合的預告了,還沒有想到下回合具體會寫一些什么。OK,咱們下回見。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM