ASP.NET MVC4 入門簡介

暖楓無敵發表於2017-09-14

1、什麼是設計模式?

模式的理解

有一面牆,現在要讓一組人翻過去。

前面三個人用了三種不同的翻牆方式。後面排隊的人發現第三

個人的方式更好。所以他們都重複第三個人的翻牆方式。

這時,我們就可以說第三個人發現了一種“模式”。

模式是一種解決問題的思路,而不是具體的做法。

 

設計模式的理解

在軟體開發領域,設計模式是為解決開發中某一類問題而提出的一種解決方案。因此,設計模式本質上是思想,而不是程式碼。設計模式追求的思想上的複用,而不是程式碼上的複用。

 

2、ASP.NET MVC概述

ASP.NET MVC是一種構建Web應用程式的框架,它將一般的MVC(Model-View-Controller)模式應用於ASP.NET框架。

MVC將Web應用程式劃分為三個主要的部分,以下是MSDN給出的定義:

模型(Model:模型物件是實現應用程式資料域邏輯的應用程式部件。 通常,模型物件會檢索模型狀態並將其儲存在資料庫中。 例如,Product 物件可能會從資料庫中檢索資訊,操作該資訊,然後將更新的資訊寫回到 SQL Server 資料庫內的 Products 表中。

檢視(View:檢視是顯示應用程式使用者介面 (UI) 的元件。 通常,此 UI 是用模型資料建立的。 Products 表的編輯檢視便是一個檢視示例,該檢視基於 Product 物件的當前狀態顯示文字框、下拉選單和核取方塊。

控制器(Controller:控制器是處理使用者互動、使用模型並最終選擇要呈現的檢視來顯示 UI 的元件。 在 MVC 應用程式中,檢視僅顯示資訊;控制器則用於處理和響應使用者輸入和互動。 例如,控制器處理查詢字串值,並將這些值傳遞給模型,而模型可能會使用這些值來查詢資料庫。

 


3、ASP.NET MVC的發展歷程

我們以一張時間軸線圖開始,瞭解一下ASP.NET MVC的發展歷程。


2007年2月,Microsoft公司的Scott Guthrie在旅途中草擬了ASP.NET MVC的核心程式。經過9個預覽版本,於2009313,正式釋出ASP.NETMVC1官方版本。

時隔一年,ASP.NETMVC220103釋出,部分主要特徵如下:

•     帶有自定義模板的UI輔助程式

•     在客戶端和服務端基於特性的模型驗證

•     強型別的HTML輔助程式

•     改善的Visual Studio開發工具

•     支援將大型應用程式劃分為域

•     支援非同步控制器

•     使用Html.RenderAction支援渲染網頁或網站的某一部分

•     新的輔助函式、使用工具和API增強

20111ASP.NET MVC3正式推出,部分主要特徵如下:

•     支援Razor檢視引擎

•     支援.NET4資料註解

•     改進了模型驗證

•     提供更強的控制和更大的靈活性,支援依賴項解析(Dependency Resolution)和全域性操作過濾器(Global Action Filter)

•     豐富的JavaScript支援,其中包括非侵入式JavaScript、jQuery驗證和JSON繫結

•     支援NuGet,可以用來發布軟體,管理整個平臺的依賴

20129ASP.NET MVC4正式釋出,新增功能主要包括:

•     ASP.NET Web API

•     增強了預設的專案模板

•     新增使用jQuery Mobile的手機專案模板

•     支援顯示模式(Display Mode)

•     支援非同步控制器的任務

•     捆綁和微小(minification)

201310ASP.NET MVC5與Visual Studio 2013一起釋出,下面列出了一些主要特徵:

•     One ASP.NET

•     新的Web專案體驗

•     ASP.NETIdentity

•     Bootstrap模板

•     特性路由

•     ASP.NET基架

•     身份驗證過濾器

•     過濾器重寫

4、建立ASP.NET MVC4應用程式

1、選擇“檔案”->“新建”->“專案”選項,如下圖所示:


2、在“新建專案”對話方塊左側的“已安裝”->“模板”->“Visual C#”列表下,選中Web選項,選擇ASP.NET MVC4 Web應用程式,將應用程式命名為MyFirstMvcProject,點選“確定”按鈕,如下圖所示:


3、在彈出的“新ASP.NET 專案”對話方塊中,選中“基本”模板,檢視引擎選擇“Razor”,同時將“建立單元測試專案”勾選上,點選“確定”按鈕,如下圖所示:


4、至此,一個新的MVC專案已經建立完成,如下圖所示:


5、ASP.NET MVC應用程式結構

新的MVC專案建立完成後,會自動向這個專案中建立一些目錄,下表介紹了這些目錄的主要用途。

目錄

用途

App_Data

用於儲存想要讀取/寫入的資料檔案

App_Start

用於儲存一些功能的配置程式碼

Content

用於儲存CSS、影象和其他站點內容

Controllers

用於儲存處理URL請求的控制器類

Models

用於儲存表示和操縱資料以及業務物件的類

Scripts

用於儲存JavaScript庫檔案和指令碼

Views

用於儲存負責呈現輸出結果的UI模板檔案

 

6、ASP.NETMVC的約定

在預設情況下,ASP.NET MVC應用程式對約定的依賴性很強,這樣就避免了開發人員配置和指定一些項,因為這些項可以根據約定來推斷。這個概念通常被稱為“習慣優於配置(convention over configration”。
    ASP.NET MVC對於程式結構的約定如下:
  1、每個Controller類的名字以Controller結尾,儲存在Controller目錄中。
  2、應用程式的所有檢視放在單獨的Views目錄下。
  3、控制器使用的檢視是在Views主目錄下的,與控制器名稱相同的子目錄中。

 

7、WebForm和ASP.NET MVC,為什麼MVC更好一些?

    ASP.NET Webform 後臺程式碼(behind code)—— 福音與詛咒

  我們已經在專案開發中使用過ASP.NETWebform技術,大家會發現它更接近視覺化設計,換句話說,開發者只需要從設計皮膚中拖拽控制元件即可完成UI,接著在behindcode中實現邏輯程式碼即可完成最後的Web頁面功能。


  所以換句話說,當你從設計皮膚中拖拽一個按鈕時,在後臺程式碼中就會生成一個button物件,你只需要在按鈕的點選事件中實現事件響應程式碼即可。

public partial class WebForm1 :System.Web.UI.Page

{

       protected void Page_Load(object sender, EventArgs e)

        {

           // Developers write code here

        }

       protected void Button1_Click(object sender, EventArgs e)

        {

           // Developers write code here

        }

  }

  當我們在頁面中拖拽一些UI元素時,雙擊它們即可在後臺程式碼中生成一系列事件響應程式碼,這些邏輯程式碼都在ASPX.CS檔案中。


  這個後臺程式碼檔案是ASP.NETWebForm的關鍵,你可以在這個檔案中應用.NET的所有特性,包括事件、委託、HTTP協議以及Session等等。

  但是這種behindcode模式有5個問題,下面我們將一一講述這5個問題,並用MVC的設計思想來分別解決這些問題。

 問題1:基於檢視的方案來解決基於行為的需求

 我們的網站最終是由使用者使用的,使用者訪問網站肯定會有特定的目的,網站要做的就是通過讓使用者的互動行為來完成其想要的目的。比如當使用者訪問一個購物網站時,也許他的互動行為會是這樣的:

·        購買產品

·        列印發票

  這些互動行為是通過按鈕點選、右鍵點選和瀏覽器URL實現的。由於這些互動都是基於HTTP協議的,所以如果我們能將這些互動行為對映到具體的一些方法上,那麼整個架構將會變得簡單很多。

  但是微軟做不到這樣,因為它要實現視覺化網頁程式設計,所以他們最終選擇了基於檢視的解決方案。


  從上圖可以看出,整個請求過程看上去很奇怪:

·        使用者發起一個HTTP請求,比如HTTPPOST / GET

·        IIS伺服器將請求對映到檢視

·        檢視呼叫頁面的生命週期,通過事件驅動,呼叫合適的互動方法

·        最後將互動的結果展現給終端使用者

  因為微軟一開始就選擇了基於檢視的設計方案,所以架構本身很難向基於使用者互動的設計思想靠攏。換句話說,當使用者發出“購買”請求時,先是訪問了檢視頁面“Shopping.aspx”,後臺邏輯程式碼在“Shopping.aspx.cs”中,頁面生命週期中會將頁面的計算結果返回給使用者。


  如果利用MVC的思想,都是基於使用者互動行為的話,那麼請求流程將會是如下所示:


 問題2:壞架構的副作用——緊耦合

  當選擇了一個錯誤的架構以後,未來將會出現很多難以解決的副作用,在ASP.NETWebForm中就出現了這個問題。儘管behindcode後臺程式碼被分離到不同的檔案中,但是ASPX.CS檔案和ASPX檔案卻緊密的聯絡在一起,這將導致系統的耦合度很高,並且很難解耦合,這是一個很頭疼的問題。


  簡單地說,我們很難將Customer.aspx.cs和CustomerDetailed.aspx簡單地剝離開,後臺程式碼已經緊緊地將其捆在一起,而且也很難複用。如果我們可以將請求先通過action,而不通過檢視view,action得到的資料再由控制器決定由哪個view展示,那麼請求的流程將會是這樣的:


  所以我們可以很方便地控制最終結果是由移動頁面展示還是正常頁面展示,如下程式碼:

publicActionResult Index(string DeviceType)

{

           if (viewType == "Mobile")

            {

                returnView("MobileView");

            }

            else

            {

                returnView("NormalView");

            }

}

 問題3HTML不是唯一的返回型別

  由於檢視view和後臺程式碼behindcode緊密耦合在一起,所以預設的返回型別就固定了,都是HTML型別。如果你想改變型別就必須設定Content-type和呼叫Response.End方法。

  如果我們建立一個Action,返回的型別由Action中指定,系統就可以在同一個action中根據不同條件輸出不同的返回型別。程式碼如下:

publicActionResult Index(string  viewType)

{

            if (viewType == "JSON")

            {

                return Json(new Customer(),JsonRequestBehavior.AllowGet);

            }

            else

            {

                returnView("DisplayCustomer", new Customer());

            }

}

 問題4:檢視和資料的靈活組合

  Webform是檢視優先的架構,所以檢視決定了展現的資料,因此檢視的擴充套件性就很差,如果遇到複雜的資料結構,這種方式就顯得力不從心了。

  但是如果是行為優先的架構的話,當我們觸發action時,action可以根據不同的請求選擇不同的資料模型和檢視結構,如下圖:


  在MVC中,你可以在不同的view中選擇相同的資料模型,比如下面的程式碼,customerdata資料既可以繫結在DetailCustomer檢視中,也可以繫結在Customer檢視中。

publicActionResult Index(string ViewName,Customer customerdata)

{

            if (ViewName =="Detailed")

            {

returnView("DetailCustomer",customerdata);

            }

            else

            {

                returnView("Customer",customerdata);

            }

}

  但這在WebForm中實現起來是非常麻煩的。

 問題5、將behind code當做普通的類來進行單元測試

  behindcode後臺程式碼在WebForm中是一個非常龐大的類,並且不能簡單地例項化。要知道WebForm是繼承於Page類的,Page類不能直接例項化,因為它有太多的依賴項。

publicpartial class WebForm1 : System.Web.UI.Page

    {

        protected void Page_Load(object sender,EventArgs e)

        {

        }

        public void Button1_Click(objectsender, EventArgs e)

        {

            Session["SomeSession"] ="Is this set";

        }

    }

  為什麼我們想要例項化Page類呢?其中一個原因就是可以方便單元測試。比如我要測試一個按鈕點選事件,用來檢查Session是否設定成功。在WebForm中的程式碼看起來不是那麼舒服:

[TestMethod]

publicvoid TestMethod1()

{

            WebApplication22.WebForm1 obj = newWebApplication22.WebForm1();

            obj.Button1_Click(this, newEventArgs());

}

  並且執行時還會丟擲一個異常:


  在MVC中,這個類變成了一個普通類,我們可以在測試工程中將它例項化,並對類裡面的屬性方法、Session、ViewBag 、 TempData等進行單元測試。

publicclass HomeController : Controller // this class is simple

{

        public ActionResult Index()

        {

            Session["SomeSession"] ="Is this set";

            return View("SomeView");

        }

}

 所以是否選擇MVC解決方案?


  從WebForm架構切換到MVC架構,我們需要做以下幾件事情:

·        將behindcode中的程式碼轉移到controller類中,並將原來的方法轉換成action方法。

·        中間層用資料模型和邏輯介面代替。

·        檢視view只用來展現資料和頁面佈局。

·        DAL層和其他層沒有什麼變化,因為它和behindcode關係不大。


  所以MVC架構中,使用者的請求分為下面3個步驟:

·        終端使用者傳送請求,路由器將請求路由到合適的Controller,Controller是邏輯實體和行為Action的集合。

·        Controller將請求對映到特定的Action。

·        Action有兩個任務,第一是獲取合適的資料,第二是將這些資料和檢視View繫結起來。Action建立資料模型,並將資料模型連線到指定View,輸出最終的相應結果。

相關文章