Linux.NET學習手記(5)

來源:互聯網
上載者:User

上一回合中,我們牛刀小試的在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,咱們下回見。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.