天天看點

【ASP.NET專題】(1)——ASP.NET MVC初探

ASP.NET MVC Framework是微軟官方提供的MVC模式編寫ASP.NET Web應用程式的一個架構.已于2009年3月19日正式釋出. MVC(Model-View-Controller)用于表示一種軟體架構模式.它把軟體系統分為三個基本部分:模型(Model),視圖(View)和控制器(Controller). 既然是一個優秀的架構,那麼就值得去學習一把,網上搜尋了許多資料,希望對于MVC的學習有幫助。

目前官方已經公布了ASP.NET MVC 2 RC,但是推薦大家還是先把1.0學好,因為一切都是相通的。

一、學習資料

1、http://www.asp.net/mvc/:這肯定是最權威的指導,它提供了MVC的下載下傳、解釋了什麼是MVC、也教會了我們如何去使用MVC。如果英文還好的話建議通過官方文檔學習。

2、http://kb.cnblogs.com/zt/mvc/:部落格園提供的ASP.NET MVC技術專題。這裡有許多國内的大牛寫一些學習筆記,相信有很多是可以把大家引入門的。同時也衷心希望CSDN也把相關專題做出來。

3、http://www.baidu.com/s?wd=asp.net+mvc&oq=asp.&f=3&rsp=1:"百度:asp.net mvc"最直接的學習方式。

4、http://www.cnblogs.com/WizardWu/archive/2009/04/18/1438809.html:一個網友寫的《快速弄懂ASP.NET MVC》

5、http://www.cnblogs.com/zhangziqiu/archive/2009/02/27/ASPNET-MVC-1.html:一個網友寫的《從0開始學習ASP.NET MVC》

二、ASP.NET MVC 1.0淺析

2.1 MVC的組成

Models:通路資料庫,裝載資料、處理業務邏輯。在項目中展現為資料實體類加業務代理類。

Views:顯示資料,使用者界面。在項目中展現為aspx頁面,偶爾可以加上code-behind。

Controller:按路由規則将請求的資料傳送給指定頁面,用于顯示;也可以把使用者輸入的資料傳遞給邏輯處理類。它可以包含簡單的驗證邏輯。不應包含資料通路邏輯。

MVC架構的運作方式如圖0所示。

【ASP.NET專題】(1)——ASP.NET MVC初探

圖0 MVC架構運作方式

2.2 為何使用MVC

提出MVC的目的無非是提高開發效率、提高可測試性。官方的ASP.NET MVC 1.0指南中指出(以下簡稱指南),基于MVC的Web應用程式有如下優點:

1、對複雜的程式管理更友善

It makes it easier to manage complexity by dividing an application into the model, the view, and the ontroller.

2、在開發上有更高的可控性

It does not use view state or server-based forms. This makes the MVC framework ideal for developers who want full control over the behavior of an application.

3、Routing使軟體設計有更多靈活性

It uses a Front Controller pattern that processes Web application requests through a single controller. This enables you to design an application that supports a rich routing infrastructure.

4、更加适合測試驅動開發

It provides better support for test-driven development (TDD).

5、團隊開發項目中有更高的可控性

It works well for Web applications that are supported by large teams of developers and Web designers who need a high degree of control over the application behavior.

同時MVC架構還有以下特點:

1、将應用程式分成各個組成部份,更有利于測試。MVC架構是基于接口的,這樣可以利用MOCK方式來替換你的實際類;做單元測試的時候,也可以不運作Contrllers,這樣的測試就更快更靈活。

2、MVC架構是可擴充的,你可以自己設計并替換視圖引擎、URL導向規則、Action的參數序列等等。同時MVC架構也支援依賴注入和控制反轉,你可以從外部注入執行個體,而不用讓類自己建立執行個體,你還可以通過配置檔案的方式建立執行個體,這樣使得測試更友善。

3、強大的URL映射元件使得你的應用程式的URL更易了解,同時具備搜尋能力。你的URL不必包括檔案路徑,這樣的設計很适合自定義查詢引擎和REST架構。

4、MVC架構仍然支援ASP.NET中的頁面、使用者控件、母版頁作為視圖的模闆;同時你也還可以使用嵌套母版頁、行内表達式(in-line expressions<%= %>)、伺服器端控件、模闆、資料綁定、本地化等等屬于ASP.NET已有的東西。

5、同時ASP.NET中的FORM驗證、Windows驗證、URL授權、Membership、角色、輸出、資料緩存、Session、Profile 狀态管理、配置、Provider架構等特性在MVC架構中仍然是可用的。

小結:ASP.NET MVC 1.0架構是基于ASP.NET的,是以他包括了ASP.NET中的幾乎所有特性。同時他為設計人員提供了一套測試的方案(當然這是所有語言平台MVC模式的共性)。在安裝了架構的VS2008中還增加了不少功能,可以友善地添加Views、Models、Controllers。

2.3 與三層結構的ASP.NET應用程式比較

與普通ASP.NET比較而言,最大的差別還是在于前台開發,背景包括的資料庫通路、邏輯處理與以往的方式沒有明顯差別,在MVC架構中,這些統稱為Model。而三層結構中,這些可以稱為資料通路層與邏輯處理層。

1、頁面開發

用這種模式開發的站點,光看頁面的代碼的确比以往少一些,但它更多地使用了頁面腳本(<% ... %>)用于顯示資料。在指南中并未提到不推薦使用伺服器端控件,但是它提供了大量的HTML HELPER,而且還允許你自己添加Helper,比如DataGridHelper,是以在MVC架構中使用這些Helper會更友善些,不過這對于熟練工來說應該影響不大,因為實際開發中我們更多使用的是Ctrl+C/Ctrl+V,複制幾個标簽和複制幾個Helper方法所花的時間差不多。可能對于新手來說,如果對标簽不熟悉的話,用這些Helper的速度會快些,但是這樣會影響新手掌握标簽,真是沖突呐。

2、資料送出

普通的ASP.Net開發,在送出資料的時候可能還需要通過設定資料綁定,或者在code-behind裡寫封裝代碼;而在MVC中,架構自動幫助你将頁面上填寫的資料封裝到事先指定的Model中,資料送出操作在MVC架構挺友善。而且在普通ASP.NET頁面中,經常會出現某個屬性無法綁回去的情況,這點在MVC中應該可以得到解決。指南中提到了Routing的使用使得MVC架構下的應用程式在操作自定義查詢時變得更友善,實際上在查詢方面跟普通方式并沒有多大差別,都是對封裝好的類進行解析。至于“URL更容易了解”,現在應用程式都是從界面上點選來實作操作,很少有人會關注URL本身吧,是以這個優點不算優點。

3、單元測試

從測試上講,MVC架構确實做得不錯,若用MOCK方式測試可以更友善,一個好的WEB應用程式設計就應該将頁面呈現與邏輯分開,這點普通ASP.NET應用程式也是可以做到的,關鍵在于設計。

4、其它

MVC架構在驗證、母版頁這些地方有幾個新特性,但與普通ASP.NET的方式大同小異,是以不仔細說了。

2.4 小結

總的來講,微軟的 ASP.NET MVC Framework 是為了讓 ASP.NET 更适合中、大型的項目,能統一規劃、控管整個網站系統的流程 (用 Controller 處理),并更有效地分工開發、日後維護 (避免許多 WebForm 裡重複出現相同功能的自定義函數)、管控某個功能在修改後對系統整體的影響,并将不同的功能作更明确地切割,讓不同專長的技術人員各司其職,也順便提高了代碼的可讀性,便于測試 (TDD, test -driven development) (減少直接綁到使用者界面中的代碼量),并達到「松散耦合 (loosely coupled)」,讓元件易于更換和重複使用。但也是以,ASP.NET 程式員必須先改變過去,把很多業務邏輯、輸入驗證、頁面切換…等雜七雜八的功能,全部寫在 Code-Behind (aspx.cs) 裡的舊習慣。

三、使用ASP.NET MVC前的準備工作

本節主要介紹下載下傳MVC源碼以及如何搭建開發環境。注意:你的PC機必須安裝好了VS 2008。

1、首先去官網下載下傳ASP.NET MVC,目前最新版本為2.0,但是對于我初學而言,我決定下載下傳1.0進行學習測試。網址為:http://www.asp.net/mvc/download/

2、下載下傳後的檔案為AspNetMVC1.msi,直接點選下一步即可。

3、然後啟動2008,點選建立項目->選擇Visual C#->選擇Web->選擇ASP.NET MVC Web Application,自己取個項目名稱就可以了(具體如下圖所示)。

【ASP.NET專題】(1)——ASP.NET MVC初探

圖1 建立MVC應用程式

其在 VS 解決方案的結構如下圖所示:

【ASP.NET專題】(1)——ASP.NET MVC初探

圖2 解決方案結構

4、點選【确定】即建立了一個預設的MVC項目.同時還會建立一個測試項目(你也可以選擇不建立), 直接将Web項目中的default.aspx設定為啟動頁, 運作項目, 一個ASP.NET MVC的項目已經運作在我的電腦上了(具體如下圖所示)。

【ASP.NET專題】(1)——ASP.NET MVC初探

圖3 浏覽首頁

5、看到該頁面的時候,恭喜你,環境搭建成功了。當然目前還不了解為什麼用MVC,後面的章節将會介紹如何利用ASP.NET MVC來協助自己。 

四、ASP.NET MVC解析

如下圖4所示。注意當你點選Home或者About的時候,浏覽器位址為:http://localhost:1750/或者http://localhost:1750/Home/About,具體原因本章節将會慢慢解釋。

【ASP.NET專題】(1)——ASP.NET MVC初探

圖4 MVC項目首頁(注意浏覽器位址)

事實上該頁的内容,是去捉 Views/Home 檔案夾底下,的 Index.aspx 的内容來呈現。其由 Global.asax.cs 配置,并用了「URL 重寫 (Url Routing)」,讓使用者可以按你自己定義的的規則來通路網站。

在圖 3 首頁的右側,會有兩個 hyperlink,可分别導向「LogOn.aspx」、「About.aspx」頁面;但 hyperlink 要導向哪一個頁面,不是寫死在 View 的頁面中 (已無 Code-Behind),而是統一由 Global.asax.cs 去定義 Routing rules,去解析當浏覽器收到 URL、表單或任何 request 時,應該要扔給哪一個 Controller 自定義類去處理;再由該個被指定的 Controller (如上圖2 裡預設自動産生的 HomeController.cs),裡面所定義的一或多個 System.Web.Mvc.ActionResult 類,以及 View 方法 (術語叫 action method),去設定要把 UI render 回哪一個 View (頁面) 去,也就是本文一開始所提到的 (如圖0所示),Model 2 架構是由 Controller 檔案,去統一控管整個 ASP.NET 系統的流程、頁面導向,而不是寫死在各個 aspx.cs 檔案裡。

以下為 Global.asax.cs 的一部分代碼,網友們可搭配參考上圖2裡 Controller、View 的結構去閱讀:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using System.Web.Routing;

namespace MovieApp

{

// 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);

}

}

}

MapRoute 方法裡的三個參數,分别代表:route name、URL、Parameter。其中第一個參數 "Default",代表了項目中的 Default.aspx (不是位于 View 檔案夾裡)。這個 URL Routing 是為了解決使用者直接通路域名時,會出現找不到檔案的情形,是以要采用這個方法,将首頁改成 Routing 到 Home/Index 上。是以當您在浏覽器的位址欄輸入:

http://localhost:端口号/Default.aspx

http://localhost:端口号

亦會導至圖2中的 Views/Home/Index.aspx。

在圖4的首頁裡,當滑鼠移到右側的 hyperlink 時,實際連結的頁面名稱 (某個 .aspx) 并不會直接顯示在浏覽器的位址欄、浏覽器下方的資訊欄裡,因為 request「轉向」的運作皆統一由 Controller 處理,亦即由圖 2 中 HomeController.cs 裡,配置的 System.Web.Mvc.ActionResult 類的 actionName 去指定,是以浏覽器的網址仍會維持 Site.Master (MasterPage) 裡的 Html.ActionLink 綁定,所配置的 actionName (即下方兩行代碼的第二個參數 "Index"、"About"),而不會如過去 ASP.NET 1.x / 2.0 般,直接在位址欄裡,顯示某一個 .aspx 的頁面名稱。

以下為 Site.master 的代碼:

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

<title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>

<link href="../../Content/Site.css" target="_blank" rel="external nofollow" mce_href="Content/Site.css" target="_blank" rel="external nofollow" rel="stylesheet" type="text/css" />

</head>

<body>

<div class="page">

<div id="header">

<div id="title">

<h1>My MVC Application</h1>

</div>

<div id="logindisplay">

<% Html.RenderPartial("LogOnUserControl"); %>

</div>

<div id="menucontainer">

<ul id="menu">

<li><%= Html.ActionLink("Home", "Index", "Home")%></li>

<li><%= Html.ActionLink("About", "About", "Home")%></li>

</ul>

</div>

</div>

<div id="main">

<asp:ContentPlaceHolder ID="MainContent" runat="server" />

<div id="footer">

</div>

</div>

</div>

</body>

</html>

Controller 除了用來控管整個網站的流程轉向外,事實上還能避免大量的代碼重複,亦即統一處理一些系統可「共享」的功能,例如:驗證使用者身份、輸入驗證 (validate)、Session 管理,或是像購物網站中,當購物車裡物品的添加、修改、移除時,任何使用者皆相同的「共通邏輯」處理;以及要結帳時,去做購物數量、單價相乘的計算動作,或将某個存儲購物明細的 Collection 資料結構對象加入 Session,最後再轉向某一個頁面 (View)。

也許你對于本文講解的概念有些模糊,下面我們看看簡單的程式是怎麼寫的,我們打開Controller/HomeController.cs,代碼如下:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

//請按照1.2.3.4.編号檢視

namespace MovieApp.Controllers

{

[HandleError] //5、這是一個規則,表示如果抛出異常将由規定頁面處理

///<summary>

///1. HomeController對應Views中的Home檔案夾

///</summary>

public class HomeController : Controller

{

///<summary>

///2. 這個東西叫Action,這個Action的名字是Index,預設情況下對應的是Views

///中此Controller(HomeController)對應檔案夾(Views/Home)下的同名aspx檔案(Views/Home/Index.aspx)

///</summary>

public ActionResult Index()

{

ViewData["Message"] = "Welcome to ASP.NET MVC!";

//4.return View();表示要展現一個aspx頁面。

//預設情況下顯示同名aspx頁面:Views/Home/Index.aspx

//當然你也可以自己指定,例如return View("index1")

//就是顯示Views/Home/Index1.aspx

return View();

}

/// <summary>

/// 3.同上所述,這個Action叫About

/// 預設情況下對應的是(Views/Home/About.aspx)

/// </summary>

public ActionResult About()

{

return View();

}

}

}

請大家從上述代碼中體會一下View/Action/Controller的關系。

現存有個問題,我如果想看到Index.aspx和About.aspx的頁面我們應該怎麼辦呢? 

繼續閱讀