來自 張子陽:http://www.cnblogs.com/JimmyZhang/archive/2009/01/01/1366475.html
這篇教程將為你提供ASP.NET MVC模型、視圖、控制器的高層次概覽。換言之,它解釋了ASP.NET MVC中的“M”、“V”和“C”。
在讀完本教程之後,你應該能夠理解ASP.NET MVC應用程式中的各個不同部分是如何一起工作的。你也應該能夠理解ASP.NET MVC應用程式與ASP.NET Web表單應用程式和動態伺服器頁面應用程式在構架上有何不同。
1. 範例ASP.NET MVC應用程式
Visual Studio用於建立ASP.NET MVC Web應用程式的預設範本包括了一個極其簡單的範例應用程式,可以使用它來理解ASP.NET MVC應用程式的各個部分。我們將會在這篇教程中利用這個簡單的應用程式。
你可以通過啟動Visual Studio2008,並且在菜單中選擇“File(檔案)”、“New Project(建立項目)”來使用MVC模板建立一個新的ASP.NET MVC應用程式(1)。在“建立項目”對話方塊,在項目類型下選擇你喜歡的程式設計語言(Visual Basic或者C#),並且在模板下選擇ASP.NET MVC Web應用程式。點擊“確定”按鈕。
圖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。正如你從檔案夾的名稱可以推測出的,這三個檔案夾包含了實現了模型、視圖和控制器的檔案。
如果你展開Controller檔案夾,你應該會看到一個命名為HomeController.cs的檔案。如果你展開Views檔案夾,你應該看到兩個子檔案夾,名稱是Home和Shared。如果你展開Home檔案夾,你將會再次看到兩個檔案,名稱是About.aspx和Home.aspx(見圖3)。這些檔案組成了這個包含在預設ASP.NET MVC模板中的範例應用程式。
圖3 - 解決方案瀏覽器視窗
你可以通過選擇功能表項目“Debug(調試)”、“Start Debugging(啟動調試)”來運行這個範例應用程式。除此以外,你可以點擊F5鍵。
當你第一次運行ASP.NET應用程式,將會出現圖4中的對話方塊,建議你開啟偵錯模式。點擊“確定”按鈕將會運行應用程式。
圖4 - 未開啟調試對話方塊
當你運行一個ASP.NET MVC應用程式,Visual Studio會在你的web瀏覽器中運行應用程式。這個範例應用程式只含有兩個頁面:Index頁面和About頁面。當應用程式第一次啟動時,將會顯示Index頁面(見圖5)。你可以通過點擊應用程式右上方的菜單連結導航到About頁面。
圖5 - Index頁面
注意一下你瀏覽器地址欄中的URL。當你點擊Home菜單連結,瀏覽器地址欄的URL將變為/Home。當你點擊About菜單連結,瀏覽器地址欄的URL變為/About。
2. 一個URL並不等同於一個頁面
當你建立一個傳統的ASP.NET Web表單應用程式,或者是一個動態伺服器頁面(ASP)應用程式,在URL與頁面之間存在一對一的對應。如果你請求伺服器上的一個名為SomePage.aspx的頁面,那麼最好在磁碟上有一個SomePage.aspx頁面。如果SomePage.aspx檔案並不存在,你將會獲得一個醜陋的404-頁面不存在錯誤。
當建立一個ASP.NET MVC應用程式時則大不相同,你鍵入到瀏覽器地址欄的URL與你應用程式中的檔案之間並沒有一個對應關係。在一個ASP.NET MVC應用程式中,一個URL與一個控制器的動作相對應,而不是磁碟上的頁面。
對於一個傳統的ASP.NET或者ASP應用程式,瀏覽器請求被映射到了頁面。在ASP.NET MVC應用程式中,瀏覽器請求被映射到了控制器動作。一個ASP.NET Web表單應用程式是以內容為中心的。而一個ASP.NET MVC應用程式則以是應用程式邏輯為中心的。
3. 理解URL路由
一個瀏覽器請求通過名叫URL路由(URL Routing)的ASP.NET MVC功能被映射到了一個控制器動作。URL路由將即將到來的請求發送到了控制器動作。
URL路由使用一張路由表來處理來到的請求。這個路由表在你的Web應用程式初次開機時建立。這個路由表建立在Global.asax檔案中。代碼清單1包含了這個預設的MVC Global.asax檔案。
代碼清單1 - Glabal.asax
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace MvcApplication1 {
public class GlobalApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = ""}
);
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
}
}
當ASP.NET應用程式第一次啟動時,將調用Application_Start()方法。在代碼清單1中,這個方法調用了RegisterRoutes()方法,並且RegisterRoutes()方法建立了預設的路由表。
預設的路由表只含有一個路由。這個預設的路由將所有到來的請求分為了三個分段(一個URL分段是正斜杠之間的任何東西)。第一個分段映射到了控制器名稱,第二個分段映射到了動作名稱,最後一個分段映射到了傳遞給動作的名為Id的參數。
例如,考慮下面的URL:
/Product/Details/3
這個URL將會被解析為像這樣的三個部分:
Controller = ProductController
Action = Details
Id = 3
注意到Controller尾碼被添加到了控制器參數的末尾。這隻是MVC的一個怪癖而已。
預設的路由包含所有三個分段的預設值。預設的控制器是HomeController,預設的動作是Index,預設的Id是一個Null 字元串。腦子裡記下這三個預設值,考慮下面的URL是如何被解析的:
/Employee
這個URL將被解析為像這樣的三個參數:
Controller = EmployeeController
Action = Index
Id = ""
最後,如果你開啟一個ASP.NET MVC應用程式而不提供任何的URL(例如,http://localhost),然後這個URL將會被解析成這樣:
Controller = HomeController
Action = Index
Id = ""
這個請求被發送到了HomeController類的Index()動作。
4. 理解控制器
控制器負責使用者與MVC應用程式互動的方式。當使用者發出瀏覽器請求時,控制器決定向使用者發回什麼樣的響應。
控制器不過是一個類(例如,一個Visual Basic或者C#類)。這個範例ASP.NET MVC應用程式套件組合含一個名為HomeController.cs的控制器,它位於Controllers檔案夾下。HomeController.cs的內容再次顯示在了代碼清單2中。
代碼清單2 - HomeConroller.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplication1.Controllers {
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()。這兩個方法對應於控制器暴露出的兩個動作。URL /Home/Index將會調用HomeController.Index()方法,而URL /Home/About會調用HomeController.About()方法。
控制器中的任何公用方法都被暴露為一個控制器動作。對此你需要多加小心。這就意味著包含在控制器中的任何公用方法都可以由任何可以訪問互連網的人調用,通過在瀏覽器中輸入正確的URL。
5. 理解視圖
由HomeController類暴露出的兩個控制器動作,Index()和About(),都返回了一個視圖。視圖含有將會發送給瀏覽器HTML標記和內容。當使用ASP.NET MVC應用程式時,一個視圖等同於一個頁面。
你必須在正確的位置建立你的視圖。HomeController.Index()動作返回了一個位於以下路徑的視圖:
ViewsHomeIndex.aspx
HomeController.About()動作返回一個位於以下路徑的視圖:
ViewsHomeAbout.aspx
一般而言,如果你想為一個控制器動作返回一個視圖,那麼你需要在Views檔案夾下建立一個子檔案夾,這個檔案夾與你的控制器同名。在子檔案夾下,你必須建立一個.aspx檔案,它的名字與控制器動作相同。
代碼清單3中的檔案含有About.aspx視圖。
代碼清單3 - About.aspx
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="About.aspx.cs" Inherits="MvcApplication1.Views.Home.About"%>
<asp:Content ID="aboutContent" ContentPlaceHolderID="MainContent" runat="server">
<h2>About Us</h2>
<p>
TODO: Put <em>about</em> content here.
</p>
</asp:Content>
如果你忽略代碼清單中的第一行,視圖剩餘的大部分是由標準的HTML構成的。你可以在這裡輸入任何你想要的HTML來修改視圖的內容。
視圖非常類似於動態伺服器頁面(ASP)中的頁面,或者ASP.NET的Web表單。視圖可以含有HTML內容和指令碼。你可以使用你所喜愛的.NET語言(例如,C#或者Visual Basic .Net)編寫指令碼。你使用指令碼顯示動態內容,例如資料庫資料。
6. 理解模型
我們已經討論了控制器,我們也討論了視圖。我們需要討論的最後一個話題是模型。MVC模型是什麼呢?
MVC的模型包含了你應用程式中的所有邏輯,這些邏輯沒有包含在視圖或者控制器中。模型應該包含你的應用程式中的所有商務邏輯和資料庫訪問邏輯。例如,如果你使用LINQ to SQL訪問資料庫,那麼你可以在Models檔案夾中建立你的LINQ to SQL類(你的dbml檔案)。
視圖應該僅包含與產生使用者介面有關的邏輯。控制器應該僅僅只包含最少量的邏輯,用於返回正確的視圖或者將使用者重新導向到另一個動作。任何其他的事情都應該包含在模型中。
通常,你應該竭盡全力建立一個豐富的模型以及一個瘦小的控制器。你的控制器方法應該只包含幾行代碼。如果一個控制器動作變得太豐富,那麼你應該考慮將這些邏輯抽取出來放置到Models檔案夾的新類中。
7. 總結
這篇教程為你提供了ASP.NET MVC Web應用程式各個不同部分的一個高層次的概覽。你學習了URL路由如何將即將到來的瀏覽器請求發往特定的控制器動作。你還學習了控制器是如何協調視圖怎樣返回瀏覽器的。最後,你學習了模型是怎樣包含應用程式的業務和資料庫訪問邏輯的。