這篇文章向你提供ASP.NET MVC 模型,視圖和控制的高度概覽。換句話說,解釋一下ASP.NET MVC中的 ‘M’, ‘V’, 和 ‘C’。
看完這篇文章以後,你應該就能理解ASP.NET MVC的不同部分是如何共同工作的。而且你也應該能夠理解ASP.NET MVC程式的架構與ASP.NET Web表單程式或ASP程式有如何的不同。
樣本 ASP.NET MVC 應用程式
用以建立ASP.NET MVC Web程式的預設的 Visual Studio 模板包括一個極其簡單的樣本程式,可以用來理解ASP.NET MVC Web程式的不同部分。我們在這個教程裡就利用這個簡單程式吧。
運行Visual Studio 2008, 選擇“檔案”,“建立”(見圖1),用MVC模板建立ASP.NET MVC程式。在“建立項目”對話方塊中,在“項目類型(P)”(Visual Basic 或者C#)中選擇你喜歡的程式設計語言,並在“模板”下選擇 ASP.NET MVC Web Application 。點擊“確定”按鈕。
圖1 建立項目對話方塊
建立完新的 ASP.NET MVC 程式後, 出現Create Unit Test Project 對話方塊(見圖2). 這個對話方塊會在解決方案中為你建立一個單獨的用來測試你的ASP.NET MVC程式的項目。選擇選項 No, do not create a unit test project 並單擊 OK 按鈕。
圖2 建立單元測試對話方塊
ASP.NET MVC 程式建立完成。你會在方案總管視窗中看到幾個檔案夾和檔案。特別是你會看到三個分別名為Models,Views和Controllers的檔案夾。顧名思義,這三個檔案夾包含了實現模型,視圖和控制器的檔案。
如果你展開Controllers檔案夾,你會看到一個名為AccountController.cs和一個名為HomeControllers.cs的檔案。展開Views檔案夾,會看到三個分別名為Account,Home和Shared的子檔案夾。展開Home檔案夾,會看到兩個分別名為About.aspx和Index.aspx的檔案(見圖3)。這些檔案組成了包括預設ASP.NET MVC模板的樣本程式。
圖3 方案總管視窗
選擇“調試”,“啟動調試”運行樣本程式。或者按F5鍵也可以。
第一次運行 ASP.NET 程式時,會出現圖4所示的對話方塊,建議你啟動調試。 點擊“確定”按鈕程式就會運行起來了。
圖4 調試未啟動對話方塊
運行ASP.NET MVC 程式時, Visual Studio 會在瀏覽器運行你的程式。樣本程式包括2個頁面:Index頁和About頁。程式初次開機時,出現Index頁(見圖5)。你可以點擊程式右上方的菜單連結導航到About頁。
圖5 Index 頁
注意瀏覽器地址欄的URL,當點擊About菜單連結時,地址欄中的URL變為 /Home/About。
關閉瀏覽器視窗回到 Visual Studio,你找不到路徑Home/About的檔案。這個檔案不存在,這怎麼可能呢?
一個URL不等於一個頁
產生傳統的ASP.NEW Web表單程式或ASP程式時,一個URL對應一個網頁。如果向伺服器一個名為 SomePage.aspx的頁面發起請求 ,那麼磁碟裡最好存在這麼一個名為SomePage.aspx的頁面。如果 SomePage.aspx 檔案不存在,將會得到一個醜陋的 404 – Page Not Found 錯誤。
相反,產生 ASP.NET MVC 程式時,在你輸入瀏覽器地址的URL和你要在程式裡找的檔案之間並沒有對應關係。在
ASP.NET MVC 程式中, 一個URL並不對應磁碟上的頁而是對應一個控制器action。
在傳統 ASP.NET 或者 ASP 程式中, 瀏覽器請求被映射到頁面。相反,在 ASP.NET MVC 程式中, 瀏覽器請求被映射到控制器action。 ASP.NET Web Form程式以內容為中心。 相反,ASP.NET MVC 程式以程式邏輯為中心。
理解ASP.NET Routing
瀏覽器請求通過一個名為 ASP.NET Routing 的ASP.NET 架構特性來獲得控制器action的映射。 ASP.NET Routing 被 ASP.NET MVC 架構用來對傳入控制器action的請求進行路由。
ASP.NET Routing 用一個路由表來處理傳入的請求。當web程式第一次運行時這個路由表就會被建立。 它是在 Global.asax 檔案中被建立的。預設的 MVC Global.asax 檔案如代碼1所示。
代碼1 – Global.asax
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using System.Web.Routing;namespace MvcApplication1{ // Note: For instructions on enabling IIS6 or IIS7 classic mode, // visit http://go.microsoft.com/?LinkId=9394801 public class MvcApplication : System.Web.HttpApplication { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = "" } // Parameter defaults ); } protected void Application_Start() { RegisterRoutes(RouteTable.Routes); } }}
ASP.NET 程式初次開機時, Application_Start() 方法會被調用。 在代碼 1中, 此方法調用 RegisterRoutes() 方法建立預設路由表。
預設路由表只包括一個路由。這個預設的路由將傳入的請求分為三段(一個URL段就是兩個斜杠間的任何東西)。第一段映射到控制器名,第二段映射到action名,最後一段映射到一個傳到action的名為Id的參數。
例如,考慮以下URL:
/Product/Details/3
這個 URL 被解析為類似這樣的3個參數:
Controller = Product
Action = Details
Id = 3
Global.asax 檔案中定義的預設路由包括所有三個參數的預設值。預設的控制器是 Home, 預設的 Action 是 Index, 預設的 Id 是Null 字元串。心裡想著這些預設值,思考一下下面的URL是怎麼解析的:
/Employee
這個 URL 被解析成類似這樣的三個參數:
Controller = Employee
Action = Index
Id =
最後,如果你不輸入任何URL(例如,http://localhost)就開啟 ASP.NET MVC 程式的話URL就像這樣解析:
Controller = Home
Action = Index
Id =
這個請求就被路由到HomeController類的 Index() action 中。
理解控制器
控制器負責控制使用者與MVC程式互動的方式。控制器包括了ASP.NET MVC程式的流量控制邏輯。控制器決定當使用者發送一個瀏覽器請求時返回什麼響應。控制器就是一個類(例如,一個Visual Basic或者C#類)。範例 ASP.NET MVC 程式包括一個位於Controllers檔案夾中名為 HomeController.cs 的控制器。 HomeController.cs 檔案內容轉載在代碼 2中。
代碼 2 – HomeController.cs
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;namespace MvcApplication1.Controllers{ [HandleError] public class HomeController : Controller { public ActionResult Index() { ViewData["Title"] = "Home Page"; ViewData["Message"] = "Welcome to ASP.NET MVC!"; return View(); } public ActionResult About() { ViewData["Title"] = "About Page"; return View(); } }}
注意 HomeController 有兩個方法,名為Index() 和About().。這兩個方法對應由控制器暴露的兩個action。 URL /Home/Index 調用 HomeController.Index() 方法而URL/ Home/ About 調用 HomeController.About() 方法。
控制器中的任何公用方法都被暴露為控制器action。對此你要特別小心。這意味著人們只要通過訪問互連網,在瀏覽器中輸入正確的URL,就可以調用控制器中的任何公用方法。
理解視圖
由HomeController暴露的 Index() 和About() 這兩個action都返回一個視圖。視圖包括HTML標記和發送到瀏覽器的內容。在ASP.NET MVC程式中視圖等同於一個頁面。你必須在正確的地方建立視圖。HomeController.Index() action 返回一個位於以下路徑的視圖:
/Views/Home/Index.aspx
HomeController.About() action 返回一個位於以下路徑的視圖:
/Views/Home/About.aspx
通常,如果你想為控制器action返回視圖,那麼你需要在Views檔案夾下建立一個與控制器同名的子檔案夾。在此子檔案夾內,你得建立一個與控制器action同名的 .aspx 檔案。
代碼3 中的檔案包含 About.aspx 視圖。
代碼3 – About.aspx
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %><asp:Content ID="aboutContent" ContentPlaceHolderID="MainContent" runat="server"> <h2>About</h2> <p> Put content here. </p></asp:Content>
如果你忽略代碼3的第一行,視圖的其餘部分包含了標準的HTML。你可以輸入任何你想要的HTML來修改視圖的內容。
視圖和ASP或ASP.NET Web表單中的頁面很相似。視圖可以包含HTML內容和指令碼。你可以用你喜歡的程式設計語言寫指令碼(例如,C#或Visual Basic .NET)。使用指令碼來顯示動態內容,例如資料庫資料。
理解模型
我們已經討論了控制器和視圖。最後一個話題就是模型了。什麼是MVC模型?
MVC 模型包含程式中的所有邏輯,而這些邏輯並不包含在視圖或控制器中。模型應該包含所有程式商務邏輯,驗證邏輯和資料庫訪問邏輯。例如,如果你用 Microsoft Entity Framework 來訪問資料庫,那麼你要在Models檔案夾中建立 Entity Framework 類 ( .edmx 檔) 。
視圖應該僅僅包含產生使用者介面的邏輯。控制器應該僅僅包含返回正確視圖的最小邏輯或者將使用者重新導向到其他action(流量控制)。其它的任何事情都應該包含在模型中。
通常,你應該為“胖”模型和“瘦”控制器而努力。控制器方法應該只包含幾行代碼。如果控制器action變得太“胖”的話,那麼就應該考慮將邏輯挪出到Models檔案夾中的一個新類中。
總結
這篇教程提供給你ASP.NET MVC Web程式不同部分的高度概覽。你學到了 ASP.NET Routing 如何將傳入的瀏覽器請求映射到特定的控制器action。你學到了控制器如何編配,視圖如何返回到瀏覽器。最後,你學到了模型如何包含程式業務,驗證和資料庫訪問邏輯。