2013年7月9日 星期二

Visual Studio 2013 Preview - ASP.NET Web Forms 加入 ASP.NET MVC 5

上一篇「Visual Studio 2013 Preview 的 ASP.NET MVC 5 初體驗」裡把 ASP.NET MVC 5 的一些改變的地方讓大家知道,另外也向各位說明了 ASP.NET Web Forms 與 ASP.NE MVC 專案可以混合不一樣的核心參考,Web Forms 專案可以包含 MVC 與 Web API,反之 MVC 專案也可以包含 Web Forms。

在今年一月的時候,我就曾經寫了一篇文章說明如何讓 ASP.NET Web Forms 專案加入 ASP.NET MVC:「ASP.NET Web Forms 專案加入 ASP.NET MVC 4」,文章裡有提到要經過很多步驟的處理之後才能夠讓 Web Forms 專案加入 MVC,而在 Visual Studio 2013 Preview 所看到的 ASP.NET 專案項目就有提供了混合專案的功能,所以未來在使用 Visual Studio 2013 開發新版 ASP.NET 網站就有提供混合專案的選項。

而這一篇文章就來說明 Visual Studio 2013 Preview 開發 ASP.NET Web Forms 專案並加入 MVC 時的一些細節,同樣的也需要說明,因為這一篇文章是以 Visual Studio 2013 Preview 為開發環境,所以之後的正式版可能會有所變動,請大家要注意。

 


測試開發環境:Windows 8.1 Preview 正體中文版、Visual Studio 2013 Preview Ultimate 正體中文版

 

一、 建立專案

首先在 VS2013 Preview 裡新增一個 ASP.NET 專案,

image

然後在「新增 ASP.NET 專案」裡所選擇的範本為 Web Forms,並且記得在「為下列項目新增資料夾及核心參考」要勾選 MVC 的項目,而 Web Forms 項目則因為我們所選取的範本為「Web Forms」而預設選擇,

image

建立好的專案架構如下,會新增 Controllers 與 Views 目錄,

image

而 Models 與 App_Start 目錄在新版的單純 ASP.NET Web Forms 專案裡也會有,如下圖,

image

另外還有不同的地方如參考、Web.Config 內容、App_Start/RouteConfig.cs 內容等等,可以在 VS 2013 Preview 去建立一個單純的 ASP.NET Web Forms 專案來做個比較。

 

二、加入 Controller

接下來我們在 Controllers 目錄裡去新增一個 Controller 檔案,要透過「支架」選項去選擇要新增的控制器,

image

在「新增 Scaffold」裡選擇「MVC 5 控制器 - 空白」

image

加入控制器,輸入控制器的名稱

image

建立完成的 DemoController.cs

image

 

三、加入 View

要加入一個新的 View 已經無法使用過往的方式在 Controller 的 Action 方法內去加入一個檢視,也必須要經由「支架」項目去加入檢視,在加入檢視之前要先在 Views 目錄去建立新的資料夾,

一開始範本所建立的 Views 目錄是空空的,只有一個 Web.Config 檔案,

image

加入一個對應 DemoController 的子目錄,目錄名稱必須對應 Controller 名稱,

image

然後在 Demo 目錄上按下滑鼠右鍵並且選擇「加入 > 支架」

image

因為沒有任何模型(Model),所以這邊所選擇的是使用「MVC 5 檢視 - 空白且不含模型」

image

然後在「加入檢視」裡輸入檢視名稱,MVC 的檢視無法使用 Web Forms 的 MsaterPage,而目前也並沒有加入 MVC 的版面配置頁,所以就取消勾選「使用版面配置」,設定好了之後就按下「加入」,就會完成加入檢視的操作,

image

image

 

四、Web Forms 網頁連結 MVC View Page

開啟 Default.aspx,然後在網頁裡加入連結

image

image

執行網站

image

點選連結

image

image

連到 MVC - Demo/Index 的頁面

image

 

五、修改 View Page 內容

在剛剛建立的 Demo/Index.cshtml 裡面的編輯操作就跟我們編輯一般 MVC 網站的 View Page 是一樣的,例如使用 Htmlhelper,

image

 

六、MVC View Page Link to Web Forms Page

如果是在 MVC 的 View 之間的連結(link)還是一樣可以使用 HtmlHelper 的 Action 產生連結或是使用 ActionLink 產生 Html HyperLink Tag,但如果是 MVC 的 View 要連結到 Web Forms Page 呢?這就無法使用 HtmlHelper 的方法來產生連結,所以這邊就要使用 Html 的 HyperLink Tag,而 Tag 裡的Gref 屬性值就直接指定 Web Forms Page 的路徑,如下:

image

而 VS 2013 Preview 裡使用新版本的 ASP.NET Web Forms 專案把今年二月正式發佈的「Microsoft.AspNet.FriendlyUrls」給包含進來,所以可以使用以下的方式產生連結到指定的 Web Forms Page,在 View Page 要使用 FriendlyUrls 的話,需要在 View Page 的上方加入 Namespace 的使用「@using Microsoft.AspNet.FriendlyUrls」,

image

上面使用 FriendlyUrl 所生的連結如下,

image

也可以產生如下所示的連結,

image

有關 ASP.NET Friendly URLs 的詳細資料可以參考以下的連結內容:

ASP.NET Friendly URLs - CodePlex

Introducing ASP.NET FriendlyUrls - cleaner URLs, easier Routing, and Mobile Views for ASP.NET Web Forms - Scott Hanselman

Friendly URLs in ASP.NET Web Forms - DeVCURRY

 

七、加入 _Layout.cshtml 版面配置頁

在加入 MVC 的 Web Forms 專案裡的 Views 並不會跟著預設產生 _Layout.cshtml 檔案,甚至連 Shared 目錄也沒有,而 MVC 的檢視示不能夠使用 Web Forms 的 MasterPage,所以我們可以自己建立,先在 Views 目錄下新增一個 Shared 目錄,

image

然後就可以在 Shared 目錄裡去新增 _Layout.cshtml 檔案,我這邊比較懶惰一些,所以我直接從另外的 ASP.NET MVC 5 專案裡去複製 _Layout.cshtml,不過我只有複製內容,而檔案本身還是需要先建立,

image

然後再把複製過來的 _Layout.cshtml 內容貼上,並且除掉並沒有使用的 Partial View 使用片段,貼上去之後會看到有錯誤紅色底線出現,

image

這是因為 Views 目錄下的 Web.Config 裡的 Namespace 沒有加入 System.Web.Optimization,所以要去 Views/Web.Config 裡去增加 Namespace 的使用,

image

Views/WebConfig 加入 System.Web.Optimization 之後記得要重新建置方案。

接著把剛才新增的 Demo/Index.cshtml 刪除,然後再新增,這一次就要選擇使用版面配置頁,

image

然後再把剛剛放在 Demo/Index.cshtml 的內容貼到新的 View Page 內容裡,

image

執行網頁,就可以看到 MVC Demo/Index 就有套用 _Layout.cshtml 了,

image

 

八、加入區域(Area)

使用 ASP.NET MVC 開發有個最大特點就是可以使用區域(Area),把相近功能的 Controller 都集中在一個 Area 裡,依據功能性來區別,最明顯的例子就是後台功能,可以在 MVC 網站專案裡建立一個 Backend 的 Area,然後這個區域裡的 Controller 與 View 就不會與前台網站混在一起,而如果是單純的一個 CMS 管理系統的話,就可以使用 Area 去細分系統類功能、檔案管理、文章管理、會員管理等等,有關 Area 的簡單說明,可以參考之前所發佈的文章「ASP.NET MVC 使用 Area - 以 Backend 後台為例」。

在「ASP.NET Web Forms 專案加入 ASP.NET MVC 4」這篇文章裡就有說到,我建議像這種混和 Web Forms 與 MVC 的網站開發,不要把 MVC 的相關目錄與檔案跟 Web Forms 的混在一起,因為容易產生開發上的雜亂情況,而且像這種混合兩種模式的網站是相當少見的,會有這種混合情況的發生應該會是網站開發技術的轉換過度時期,例如原本是 Web Forms 開發的網站,但有些新功能是曾經有使用 MVC 開發過,但是要把 MVC 所開發的功能轉換為 Web Forms 會比較困難而且開發成本太高,所以選擇在 Web Forms 網站裡加入 MVC,讓以前開發過的功能可以移植到 Web Forms 網站;還有另一種情況就是 Web Forms 網站要轉移為 MVC,但是無法馬上就讓 Web Forms 網站轉換為 MVC,以分階段的方式,慢慢的將網站功能逐漸改為 MVC 架構。

不管哪一種情況(可能有我未曾想過的狀況),我都強烈建議使用 Area 的方式來開發 MVC,因為在 Areaa 裡面,各個 Area 可以視為一個小網站,在團隊開發上比較不會有開發互相影響的情況,在管理上也十分容易與清楚。

加入 ASP.NET MVC 的區域也是需要透過「支架」,我們在網站專案上按下滑鼠右鍵選擇「加入 > 支架」,

image 

接著在「新增 Scaffold」裡選擇「MVC 5 區域」

image

「加入區域」,這邊輸入區域名稱

image

按下「加入」之後就會在網站專案裡增加一個 Areas 目錄,這個 Areas 目錄裡有個 Backend 的子目錄,Backend 目錄裡有屬於該區域的 Controllers、Models、Views 目錄,往後如果有繼續增加其他的區域,就會在 Areas 目錄下載增加子目錄,如此一來 MVC 開發的功能就可以集中在這裡,而不會與外面的 Web Forms 混在一起了,

image

加入 Controller 與 View 檔案的方式就跟上面介紹的一樣,另外我在 Views 也增加 Shared 目錄以及 _Layout.cshtml,各個 Area 可以擁有自己的 Layout 版面配置頁,也可以使用外面共用的 _Layout.cshtml,

image

image

分別在 Web Forms 的 Default.aspx 與 MVC Demo/Index 去增加連結到 Backend/Home/Index 的 HyperLink,

image

image

上面的步驟都完成之後,在重建專案後就可以執行網站來看結果,結果卻是看到這樣的錯誤,

image

甚至於在 MVC Demo/Index 頁面上要連結到 Backend/Home/Index 的超連結都長得跟我們所認知的完全不同,

image

這兩個狀況發生的原因在於 App_Start/RouteConfig.cs 裡面,以下是預設的內容,

image

這邊我們因為有加入 MVC 的 Areas,必須要讓系統知道 Areas 裡面的 route 設定,所以必須要在 App_Start/RouteCoinfig.cs 的 RegisterRoutes() 方法內加入 AreaRegistration.RegisterAllAreas(),而且位置還必須要在 routes.EnableFriendlyUrls() 上面,

image

重新建置方案之後再執行網站,就可以看到 Backend/Home/Index 能夠正常瀏覽,

image

而且在 Demo/Index 裡的連結也恢復到我們所熟悉的樣式,

image

 

Visual Studio 2013 Preview 的 ASP.NET Web Forms 網站加入 MVC 內容的開發就簡單介紹到這裡,其實還有很多比較細節的地方並沒有再深入探討,日後有機會再說。

 


其實要在 ASP.NET Web Forms 網站裡加入 MVC 來做混合開發,這真的是一件很累人的一件事情,不論是之前要手動做整合還是現在由系統直接幫我們做核心整合,不管那一種都是一樣,一開始的核心整合都只能算是小事而已,比較麻煩的是在開發之後兩個不同架構之間的資料傳遞與功能、程式整合,看不到的事情還有很多很多,各自開發 Web Forms 網站、MVC 網站都已經會有一堆問題了,更何況是把兩者給混一起。

所以最後的建議是,除非必要、萬不得已、逼不得已或者是已經造成你生命財產的立即危害,不然千萬不要這麼做,既始官方系統已經提供功能可以讓你這麼做,還是勸你不要混合兩種架構做開發。

如果你是員工,你對於 Web Forms 開發相當熟悉,無論是你有興趣學習 MVC 或是公司要你學 MVC,請千萬不要認為 Web Forms 裡加入 MVC 來開發會是一件好事,要學習 MVC,最好的方式就是拋開 ASP.NET Web Forms 的所有觀念,拋下 DataSet, DataTable, DataSource Control 等等弱型別,還有那些看起來很方便但是卻是限制多多的 Server Controls,再來就是完全忘記 UpdatePanel,反正就是把自己當成初學程式的菜鳥,以這樣的心態去學習 ASP.NET MVC,並且每次的練習都是使用「純」ASP.NET MVC 來開發,Web Forms 混合 MVC 這件事就當沒發生過。

如果你是老闆,你公司已經有一堆 Web Forms 所開發的網站或是產品,無論是對 Web Forms 開發有疑慮而想換 MVC,或是客戶要求,或是撞到頭、跌一跤而突發異想地要改用 MVC 來做開發,但因為現有人力對於 MVC 技術並不了解甚至沒有接觸過,又想要讓開發可以逐步改用 MVC,當有這個情況時,也請千萬不要考慮 Web Forms 混合 MVC,請務必為你公司員工的健康與他們的家人著想,用單純的 ASP.NET Web Forms 開發都會搞得人仰馬翻了,更何況是把一個不熟悉的開發技術給加進來,而且還是混在一起開發。

總之,最後一句話,除非必要,不然不要用 ASP.NET Web Forms 與 MVC 的混合架構來開發,當做練習還可以,但用在實際的專案、產品上,萬萬不可。

 

以上

沒有留言:

張貼留言

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。