正如標題「7天玩兒轉 ASP.NET MVC」所言,這是個系列文章,所以將會向大家陸續推出 7 篇。設想一下,一天一篇,你將從一個愉快的周一開始閱讀,然后在周末成為一個 ASP.NET MVC 開發者。這很酷吧。
第一天是熱身運動,這篇我們將圍繞 Controller 和 Views 實踐兩個 Labs。在每個 Lab 之中都伴隨著一些 Question 和 Answer。所以文章的主體框架是 Lab 和 Q&A。
我們只需要 Visual Studio 工具就可以開始 ASP.NET MVC 之旅。你可以通過Visual Studio 官網下載所需版本。
許多 ASP.NET 開發者第一次接觸 MVC 時會認為它是區別于 Webforms 的,會認為它是一個全新的技術。確實如此,如果說 ASP.NET Webforms 是一個創建 Web application 的框架,那么 ASP.NET MVC 就是一個更棒的架構體系,它以一種更合理的方式來組織和放置我們的代碼。
不可否認的是,ASP.NET Webforms 在過去十多年都非常流行,從 VB 開始,微軟就開始傳經布道 RAD 和 Visual PRogramming 的方法。連微軟的開發工具都稱作 Visual Studio,可見一斑。
通過使用 Visual Studio,開發者能通過拖拽的方式將 UI 構件放置到設計界面,Visual Studio 便自動為這些構件產生 C# 或者 VB.NET 代碼。這些可被稱作為「Code Behind」 ,在「Code Behind」區域內,開發者可以來寫一些邏輯代碼。
所以微軟的 Visual RAD 方法實際上就是兩件事,UI 和 Code Behind。例如 ASP.NET Webforms,有 ASPX 和 ASPX.CS;對于 WPF,有XAML 和 XAML.CS,不一而足。
既然 ASP.NET Webform 如此成功,為什么微軟還要考慮創建 ASP.NET MVC 呢?主要原因是出在 ASP.NET Webform 的性能上??梢詮膬蓚€性能角度考慮:
1.響應時間:Server端響應請求的時間是多少?2.帶寬消耗:多少數據被傳輸?
我們來嘗試解釋為什么 ASP.NET Webforms 的響應時間很慢。通過一個小的負載測試,我們發現 ASP.NET MVC 比 ASP.NET Webforms 快2倍左右。
假如 ASPX 有這樣一段關于 Text Box 的簡單代碼。
<asp:TextBox ID="TextBox1" runat="server">
然后為 Text Box 寫一些后臺邏輯代碼,為它進行賦值和背景色的操作。
protected void Page_Load(object sender, EventArgs e) { TextBox1.Text = "Make it simple"; TextBox1.BackColor = Color.Aqua;}
運行程序后,將會在 HTML 頁面看到輸出。
如果你查看 HTML 的源代碼,它是這樣的:
<input name="TextBox1" type="text" value="Make it simple" id="TextBox1" style="" />
現在停止閱讀,閉上眼睛思考片刻:
1.這真的是一個創建 HTML 的高效方式嗎?我們真的需要開始這樣一個漫長的服務器響應之旅而只是為了在瀏覽器上顯示如此簡單的頁面嗎?2.難道開發者們不能直接寫 HTML 頁面嗎,難道很難寫?
事實上,每一次請求都會有一次 Conversion 邏輯在運行,它用于轉換 HTML 輸出的控件。當我們輸出的控件是一些 Grids 表格, Tree View 樹形控件等一些復雜的 HTML 頁面時,這種轉換將會變得更耗時,并且非常復雜,使得等待時間更長。
為了解決這個問題,開始拋棄「Code Behind」吧,寫一些純凈的 HTML。
長期從事 ASP.NET 的開發者一定非常熟悉 Viewstate,它能夠自動保存 post 返回的狀態并且減少了開發時間。但是正是由于這種開發時間的減少帶來了巨大的代價,Viewstate 增加了頁面的大小。通過負載測試,對比 ASP.NET MVC,我們發現 Viewstate 增加了近兩倍的頁面大小。
大小的增加是由于 Viewstate 產生了額外的字節。下圖是 Viewstate 的截圖快照。也許有人會反駁放棄 Viewstate 的觀點,但是對于開發者而言,如果有其它選擇,他們會嘗試其它選擇。
為了解決這個問題,開始拋棄 Server 控件吧。
因為我們都是通過 ASP.NET 控件和后臺代碼來編寫應用,所以我們沒有辦法來決定什么樣的 HTML 被輸出,也不知道它們的效率是如何的。例如我們可以看一段 ASPX 代碼,你可以試猜想一下什么樣的 HTML 將被產生。
<asp:Label ID="Label1" runat="server" Text="I am label"> <asp:Literal ID="Literal1" runat="server" Text="I am a literal"> <asp:Panel ID="Panel1" runat="server" Text="I am a panel">
Label 控件會生成 DIV 還是 SPAN 標簽?如果你運行一下代碼會發現,Label 控件被轉換為一個 SPAN,Literal 控件被轉換為一個簡單的 Text,而 Panel 控件則被轉換為一個 DIV。
<span id="Label1">I am label</span> I am literal <div id="Panel1">I am panel</div>
因此與其使用 Server 控件來生成 HTML,倒不如直接手寫一些 HTML 來實現一些 HTML 控件。
所以,解決方案便是,不要再使用 Server 控件,直接編寫一些 HTML。 直接編寫 HTML 也帶來一些好處,這使得 Web 設計者能夠和開發團隊緊密工作。Web 設計者可以使用 Dreamweaver 或者 FrontPage來獨立設計并獲取 HTML 代碼。如果我們使用了服務器控件,這些設計工具便不能很好地識別。
如果你看到過專業的 ASP.NET Webform 項目,你會發現它的后臺代碼經常會囊括很大的代碼量,并且代碼真的很復雜。這些代碼繼承「System.Web.UI.Page」類,而這個類也不是一個常規的類,它不可以被重用或者實例化。換言之,你永遠無法在一個 Webform 類里做這樣的事情:
WebForm1 obj = new WebForm1(); obj.Button1_Click();
因為「WebForm」類沒有「Request」和「Respnse」對象是不能夠被實例化的??梢詮南旅娴拇a中看到「WebForm」的「ButtonClick」事件代碼,從這段代碼中你就可以看到為什么實例化會很難實現。
protected void Button1_Click(object sender, EventArgs e) { // The logic which you want to reuse and invoke}
基于之前所說的后臺代碼無法直接實例化,所以可想而知的是,單元測試或自動化測試都是非常困難的。開發者只能自動運行應用進行手動測試。
通過之前的分析,我們發現 ASP.NET Webforms 的兩個關鍵因素:「Code Behind」和「Server Controls」,即后臺代碼和服務器控件。它們影響的代價和解決方案如下圖所示:
我們需要的解決方案便是將后臺代碼遷移到獨立的簡易類庫,并且放棄 ASP.NET Server 控件,寫一些簡單的 HTML 頁面。 簡而言之,解決方案就像如下圖的形象說明,將 Web Form「減肥」為 MVC。
正如我們之前所討論的,后臺任務和服務器控件是問題的根源。所以如果你看一下當前的 Webform 架構體系就會發現,開發者使用的幾乎就是 3 層架構體系。
這 3 層架構體系包含了 UI,這個UI實際上包含了 ASPX 和 后臺代碼。
ASP.NET MVC 包含了三部分,即 Model,View 和 Controller。Controller 負責后臺邏輯代碼。View 是純凈的 HTML 頁面。Model 是中間數據層。
這里有兩個主要的改變,其一是 View 變為簡單的 HTML 頁面,其二是后臺代碼轉換為簡單的 .NET 類,我們稱之為 Controller。
ASP.NET MVC的請求流如下:
第一步:首先觸發 Controller。
第二步:依據行為 Controller 創建 Model 對象。Model 反過來通過調用數據接口層來向 Model 對象填充數據。
第三步:填充完的 Model 對象將數據傳輸給 View 層,然后展示出來。
現在我們已經理解 ASP.NET MVC 的各個組件了。接下來開始深入學習每個組件,并且做一些小的 Lab。我們將從 Controller 開始,因為它是 MVC 架構體系的核心。
為了理解Controller,我們首先要理解「用戶交互邏輯」的概念。
什么是交互邏輯?
你是否仔細想過,當終端用戶在瀏覽器上敲下一個 URL 并按下回車后,會發生什么事情?
瀏覽器發送一個請求給服務器,服務器再做出響應。
通過這種方式的請求,客戶端嘗試與服務器進行交互。服務器能夠返回響應是因為服務器已經有了一些邏輯來處理這些請求。這個邏輯實際上承載了用戶的請求以及用戶與服務器的交互行為,這便是用戶交互邏輯。
存在這樣一種可能,服務器返回的響應是一個 HTML 響應。這個 HTML 包含了一些輸入框或者提交按鈕組件。
當點擊「SaveCustomer」按鈕時,會發生什么事情?
如果你的回答是「一些事件處理器來處理這個按鈕點擊」,那么就錯了。
現實是 Web 編程是沒有事件的概念的。一種情況是,微軟為 ASP.NET Webforms 為我們寫了一些代碼,并給人一種事件驅動編程的感覺。實際上,這只是一個錯覺或者幻想。
當按鈕被點擊后,一個簡單的 HTTP 請求就被發送到服務器上。這次不同的是,「Customer Name」,「Address」和「Age」的值都將伴隨著請求被發送。從根本上說,如果發生了請求,那么服務器就會根據已經寫好的邏輯發出返回響應,簡而言之,服務器上一定存在一些用戶交互邏輯。
在 ASP.NET MVC 中,最后一個字母「C」就代表的是 Controller,它是用于處理用戶交互邏輯的。
1.打開 Visual Studio 2013 或更高版本,點擊 文件 > 新建 > 項目。
2.選擇 Web 應用,填寫應用名稱,選擇應用路徑,點擊確定。
3.選擇 MVC 模板文件
4.點擊更改權限,在對話框中選擇「無權限」。
5.點擊確定即可。
1.在資源管理器中,右擊「Controller」文件夾,點擊 添加 > 控制器。
2.選擇 MVC 5 控制器,點擊添加。
3.將控制器命名為「TestController」,然后點擊添加。
有一點非常重要,不要刪除「Controller」這個單詞,它是控制器的關鍵字。
打開剛剛創建的「TestController」類,你會發現里面有一個方法叫「Index」,將這個方法刪除,然后創建一個新的公開方法,稱為「GetString」。
public class TestController : Controller { public string GetString() { return "Hello World is old now. It's time for
新聞熱點
疑難解答