MVC概念html
MVC是一種架構設計模式,該模式主要應用於圖形化用戶界面(GUI)應用程序。那麼什麼是MVC?MVC由三部分組成:Model(模型)、View(視圖)及Controller(控制器)。數據庫
Model即應用程序的數據模型。任何應用程序都離不開數據,數據能夠存儲在數據庫中、磁盤文件中,甚至內存中。Model就是對這些數據的抽象,不論數據採起何種存儲形式,應用程序老是可以經過Model來對數據進行操做,而沒必要關心數據的存儲形式。數據實體類就是經常使用的一種Model。例如,一個客戶管理應用程序使用數據庫來存儲客戶數據,數據庫表中有一個客戶表Customer,相應的程序中通常會創建一個數據實體類Customer來與之對應,這個實體類即便客戶表的Model。編程
View是應用程序的界面。用戶經過View來操做應用程序,完成與程序的交互。View提供了可視化的界面來顯示Model中定義的數據,用戶經過View來操做數據,並將對Model數據操做的結果返回給用戶。在桌面應用程序中,View多是一個或多個Windows窗體。在Web應用程序中,View是由一系列網頁構成,在ASP.NET網站中即爲.aspx頁面。設計模式
Controller 定義了程序的應用邏輯。用戶經過View發送操做命令給Controller,由Controller按照程序設計的邏輯來更新Model定義的數據,並將操做結果經過View返回給用戶。服務器
MVC的歷史架構
MVC這一律念最先由美國教授Trygve Reenskaug於1979年提出。1988年MVC這一設計模式正式在《A Cookbook for Using the Model-View-Controller User Interface Paradigm in Smalltalk -80》一書中提出。伴隨着微軟Windows操做系統的迅速發展與普及,圖形化用戶界面應用程序逐漸成爲主流,不少編程語言都出現了MVC框架,以方便開發人員使用該模式來設計應用程序。這些框架中大部分都是針對Web應用程序。mvc
.NET Web開發中MVC設計模式的實現框架
ASP.NET 1.x中使用了CodeBehind技術,完全終結了傳統ASP程序開發的夢魘:程序邏輯與HTML界面元素混雜在一塊兒。CodeBehind技術將表明程序界面(View)的.aspx文件與邏輯(Controller)代碼.vb/.cs文件的分離便是一種MVC式的設計。ASP.NET 2.0中又出現了CodeBeside技術,即一個.aspx文件能夠有多個.vb/.cs文件,這又方便了界面與邏輯代碼的進一步分離。編程語言
2008年3月微軟發佈了針對ASP.NET 3.5 的MVC框架 (Preview 2 版本)。這是一個真正意義上的ASP.NET MVC框架。該框架能夠說是對以前爲開發人員所熟悉的基於Web Form的應用程序開發方式的"顛覆"。變化可謂"震撼":ide
1. 使用URL Routing技術:Web程序的URL再也不是指向具體的物理頁面.aspx,而是指向某個Controller的某個方法。一個典型的MVC架構的程序,其URL可能以下所示:
http://www.mysite.com/Customer/Index
使用該MVC架構的程序其URL沒必要有文件擴展名。上面這個URL中的Customer即爲Controller的名字。而Index是Customer定義的一個方法名。
2. Web程序的界面.aspx再也不使用服務器端的Form:
<asp: form runat="server"></form>
那麼與服務器端的Form相關的Postback以及頁面生命週期的事件也不存在了。
3. 頁面中再也不有View State。MVC下將不能使用View State來存儲程序狀態信息。
4. 再也不提供依賴於服務器端Form的服務器控件事件,開發人員熟悉的Button_Clicked事件在MVC下將再也不須要。
NET MVC示例
安裝完 ASP.NET MVC Preview 2後,VS2008中會添加一個新的項目模板"ASP.NET MVC Web Application", 以下圖所示
新建該項目後, VS2008自動生成項目的文件結構以下, MVC三個組成部分各有一個文件夾來存儲各自的程序文件。
前面提到的URL Routing即在Global.asax.cs中設置:
public class GlobalApplication : System.Web.HttpApplication { public static void RegisterRoutes(RouteCollection routes) { // 注意: IIS7如下的IIS版本需將URL格式設置爲 "{controller}.mvc/{action}/{id}" to enable
routes.Add(new Route("{controller}.mvc/{action}/{id}", new MvcRouteHandler()) { Defaults = new RouteValueDictionary(new { action = "Index", id = "" }), });//設置URL Routing格式
routes.Add(new Route("Default.aspx", new MvcRouteHandler()) { Defaults = new RouteValueDictionary(new { controller = "Customer", action = "Index", id = "" }), });//設置默認URL指向Customer Controller的Index方法 }
protected void Application_Start(object sender, EventArgs e) { RegisterRoutes(RouteTable.Routes); } } |
【代碼1】:Global.asax.cs
下面來實現Customer 的Model、Controller及View:
Model: 在項目中的Model文件夾下,新建一個"Linq to SQL Classes",將Northwind數據庫中的Customer表拖拽到其設計視圖中。這樣就完成了Customer對應的Model。如圖4
Controller: 在項目中的Controller文件夾下,新建一個"MVC Controller Class",命名爲CustomerContoller.cs。 在此類中添加一個公有方法Index,此方法及爲在Global.asax.cs中設置好的默認URL所映射的方法。
public class CustomerController : Controller { public void Index(string id) { Northwind.Models.NorthwindDataContext dc = new Northwind.Models.NorthwindDataContext(); IList<Northwind.Models.Customer> customers = dc.Customers.Take(10).ToList();//取數據庫中的10個Customer記錄 RenderView("Index", customers);//返回Index View } } |
【代碼2】:CustomerController.cs
View: 上面Index方法的代碼表示CustomerContoller的Index方法執行後,須要返回一個名稱爲Index的View,以便將數據呈現給用戶。下面來添加這個Index View:在項目的View文件中,新建一個子文件夾Customer。與Customer Controller有關的View將保存在此文件夾下。新建一個"MVC View Class"並命名爲Index.aspx。在前面的RenderView("Index", customers)方法中,customers參數是Controller傳遞給View所需的數據,該參數的類型爲IList<Northwind.Models.Customer>。爲了在View中方便使用此強類型的數據,View.aspx.cs使用了以下代碼:注意粗體部分
public partial class Index : ViewPage<IList<Northwind.Models.Customer>> { } |
【代碼3】:Index.aspx.cs
View.aspx代碼以下:ViewData這一成員變量的類型及爲上面提到的IList<Northwind.Models.Customer>類型。
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Edit.aspx.cs" Inherits="Northwind.Views.Customer.Edit" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title></title> </head> <body> <div> <table> <tr> <td>Edit</td> <td>Customer ID </td> <td>Company Name </td> <td>Contact Name </td> <td>Contact Title </td> </tr> <% foreach (Northwind.Models.Customer customer in ViewData) {%> <tr> <td><a href="Customer.mvc/Edit/<%= customer.CustomerID %>">Edit</a></td><!—URL指向Customer Contoller的Edit方法 --> <td></td> <td> <%= customer.CustomerID %></td> <td> <%= customer.CompanyName %></td> <td> <%= customer.ContactName %></td> <td><%= customer.ContactTitle %></td>
</tr> <%} %> </table> </div> </body> </html> |
【代碼4】:Index.aspx
下面來實現Customer Controller的Edit方法。在CustomerController.cs中添加以下代碼:
public void Edit(string id) { Northwind.Models.NorthwindDataContext dc = new Northwind.Models.NorthwindDataContext(); Customer c = dc.Customers.Single(cus => cus.CustomerID == id);//從數據庫中取出參數id所對應的的一個Customer記錄
RenderView("Edit", c);//返回Edit View |
【代碼5】:CustomerController.cs中的Edit方法
相應的在項目中的View/Customer/文件夾下,添加Edit View Edit.aspx:
public partial class Edit : ViewPage<Northwind.Models.Customer> { } |
【代碼6】:Edit.aspx.cs
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Edit.aspx.cs" Inherits="Northwind.Views.Customer.Edit" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title></title> </head> <body> <!—下面的 html form 將用戶的輸入提交到Customer Contoller的Update方法 --> <%using( Html.Form<Northwind.Controllers.CustomerController>(cc=>cc.Update(ViewData.CustomerID))){ %> <div> Customer ID: <%= ViewData.CustomerID %> <br /> Company Nmae: <%= Html.TextBox("Customer.CompanyName", ViewData.CompanyName) %> <br /> Contact Name: <%= Html.TextBox("Customer.ContactName",ViewData.ContactName) %><br /> Contact Title: <%= Html.TextBox("Customer.ContactTitle",ViewData.ContactTitle) %> </div> <%= Html.SubmitButton("Save") %> <%} %> </body> </html> |
【代碼7】:Edit.aspx
代碼7中使用了MVC框架中的一個幫助類Html。此類能夠生產View中經常使用的界面元素,例如 html form,文本輸入框等。
下面來實現CustomerController的Update方法:
public void Update(string id) { Northwind.Models.NorthwindDataContext dc = new NorthwindDataContext(); //從數據庫中取出參數id所對應的的一個Customer記錄: Customer cust = dc.Customers.Single(c => c.CustomerID == id); //將Edit View中的用戶的更改賦值到cust對象: BindingHelperExtensions.UpdateFrom(cust, Request.Form); dc.SubmitChanges(); RedirectToAction("Index");//跳轉到Index View } |
【代碼8】:CustomerController.cs中的Update方法
上面的代碼經過ASP.NET MVC框架實現了Customer的列表、編輯及更新功能,能夠看出MVC將應用程序的Model、View及Controller三部分"優雅的"分離,真正實現了高內聚、低耦合的靈活架構,大大下降了程序的複雜性,提升了可擴展性及可重用性。這一框架對Web開發帶來的影響不只是是技術上的變化,更是Web程序設計思想的變化 -- Web程序再也不是一些列功能頁面的集合,而是又Controller控制的功能單元的集合,Web程序更像是一組經過其URL對外開放的"API"。