為什么需要了解ASP.NET Core MVC的前世今生


我們就擦肩而過了
有趣
有用
有態(tài)度
ASP.NET Core MVC 是一個微軟公司的web應(yīng)用開發(fā)框架, 結(jié)合了MVC架構(gòu)的高效簡潔, 敏捷開發(fā)的思想和技術(shù), 以及.NET平臺最優(yōu)秀的部分. 在這一章中, 你將了解到微軟為什么要創(chuàng)建ASP.NET Core MVC, 將它和前輩以及替代品進(jìn)行比較, 最后瀏覽ASP.NET Core MVC的新特性.

了解ASP.NET Core MVC的歷史
最初的ASP.NET誕生于2002年, 當(dāng)時微軟想要保持傳統(tǒng)的桌面應(yīng)用開發(fā)的霸主地位, 將因特網(wǎng)視為潛在威脅. 圖1-1展示了當(dāng)時微軟的技術(shù)棧.
ASP.NET Web Forms: 一組UI組件(如頁面, 按鈕等) 加上一個有狀態(tài)的面向?qū)ο蟮腉UI編程模型
ASP.NET: 一組在IIS中承載.NET應(yīng)用程序的方法, 使用HTTP請求和響應(yīng)進(jìn)行交互
.NET: 一個多語言代碼托管平臺(當(dāng)時是全新的, 本身就是一個里程碑)

ASP.NET Web Forms
微軟使用Web Forms技術(shù), 將用戶界面(UI)建模為服務(wù)端控制的對象的層次結(jié)構(gòu), 來隱藏本身便具有無狀態(tài)性的超文本傳輸協(xié)議(HTTP)和當(dāng)時許多開發(fā)者不熟悉的超文本標(biāo)記語言(HTML). 每個控件都在各個請求之間跟蹤自己的狀態(tài), 在需要時將自己呈現(xiàn)為HTML, 并自動將客戶端事件(如點(diǎn)擊按鈕)與相應(yīng)的服務(wù)端事件處理程序連接起來. 事實(shí)上, Web Forms是一個巨大的抽象層, 用于在Web上呈現(xiàn)傳統(tǒng)的事件驅(qū)動GUI.
這個想法基于一種讓W(xué)eb開發(fā)感覺和桌面應(yīng)用開發(fā)相同的理念. 開發(fā)者可以從有狀態(tài)的UI角度來思考, 不需要考慮一系列獨(dú)立的HTTP請求和響應(yīng). 由此微軟可以將Windows桌面開發(fā)大軍無縫過渡到Web應(yīng)用的新世界.

ASP.NET Web Forms 出了什么問題?
傳統(tǒng)的ASP.NET Web Forms開發(fā)在理論上是好的, 但是實(shí)際情況要復(fù)雜得多:
視圖狀態(tài)(View State)負(fù)擔(dān): 在請求之間維護(hù)狀態(tài)的機(jī)制(被稱為視圖狀態(tài), View State)導(dǎo)致服務(wù)端和客戶端之間的大塊數(shù)據(jù)傳遞, 即使在最平常的Web應(yīng)用中也會達(dá)到幾百KB的數(shù)據(jù)量. 并且這些數(shù)據(jù)在每個請求中都會跑一個來回, 導(dǎo)致響應(yīng)變慢, 又增加了服務(wù)器的帶寬占用.
頁面生命周期: 將客戶端事件連接到服務(wù)端事件處理程序代碼的機(jī)制是頁面生命周期的一部分, 很復(fù)雜也很脆弱. 基本沒有開發(fā)者能在運(yùn)行時成功操作控件的層級關(guān)系而不產(chǎn)生試圖狀態(tài)錯誤, 一些事件處理程序也會莫名其妙地失敗.
錯誤的關(guān)注點(diǎn)分離: ASP.NET Web Forms的后端代碼模型提供了從HTML標(biāo)記中提取應(yīng)用程序代碼成為單獨(dú)的后端類的方法, 以分離邏輯層和表現(xiàn)層. 但事實(shí)上, 開發(fā)人員更愿意在機(jī)型的后端類中將表現(xiàn)層代碼(如操作服務(wù)器端的控件樹)和邏輯層代碼(如操作數(shù)據(jù)庫數(shù)據(jù))混合起來. 這最終導(dǎo)致了應(yīng)用程序的脆弱和不智能.
對HTML的有限控制: 服務(wù)器端控件將自己渲染為HTML, 但不一定是你想要的HTML. 在ASP.NET的早期版本中, 輸出的HTML不滿足Web標(biāo)準(zhǔn), 也不能很好的使用層疊樣式表(CSS). 服務(wù)器端控件生成不可預(yù)知的復(fù)雜ID屬性, 很難被JavaScript獲取到. 這些問題在最近的Web Forms發(fā)行版中有所改善, 但仍然很難獲取你所期望的HTML.
漏洞百出的抽象: Web Forms試圖盡可能地隱藏HTML和HTTP. 當(dāng)你嘗試實(shí)現(xiàn)自定義的行為時, 經(jīng)常會陷入抽象的泥潭中. 這迫使你對回傳事件機(jī)制進(jìn)行逆向工程, 或者執(zhí)行遲鈍的動作, 來生成想要的HTML.
可測試性差: Web Forms的設(shè)計者們當(dāng)初并沒有預(yù)料到自動測試會成為軟件開發(fā)中至關(guān)重要的一部分. 他們設(shè)計的緊密耦合的架構(gòu)不適合進(jìn)行單元測試. 集成測試也很困難.
Web Forms并非一無是處. 微軟在提高標(biāo)準(zhǔn)兼容性和簡化開發(fā)過程上做了很大努力, 甚至將最初的ASP.NET MVC框架的一些特性應(yīng)用到了Web Forms上. 當(dāng)你想快速看到結(jié)果時選擇Web Forms是很好的, 你可以在一個工作日內(nèi)將一個相當(dāng)復(fù)雜的Web應(yīng)用程序運(yùn)行起來. 但除非你在開發(fā)過程中足夠仔細(xì), 否則你會發(fā)現(xiàn)你創(chuàng)建的應(yīng)用非常難以測試和維護(hù).

?最初的MVC框架
在2007年10月, 微軟在現(xiàn)有的ASP.NET平臺上發(fā)布了一個新的開發(fā)平臺, 作為對對Web Forms的批評和競爭對手(如Ruby on Rails)的直接回應(yīng). 新平臺被稱為ASP.NET MVC框架, 反映了Web應(yīng)用開發(fā)的新型趨勢, 如HTML和CSS標(biāo)準(zhǔn)化, RESTful web服務(wù), 游戲的單元測試, 和開發(fā)者應(yīng)該擁抱HTTP的無狀態(tài)本質(zhì)的理念.
現(xiàn)在看來, 最初的MVC框架的基礎(chǔ)理念是顯而易見的, 但在2007年, .NET web開發(fā)的世界是缺少這些東西的. ASP.NET MVC框架的推出讓微軟的web開發(fā)平臺重新走向現(xiàn)代.
MVC框架也標(biāo)準(zhǔn)了微軟態(tài)度的重要轉(zhuǎn)變, 它原本嘗試控制web應(yīng)用開發(fā)工具鏈的所有東西.
微軟在MVC框架中采納了新的理念, 如基于開源工具構(gòu)建(如jQuery), 接受設(shè)計約定, 采用競爭對手(更成功的)的最佳實(shí)踐, 并對開發(fā)者公布了MVC框架的源碼.

?最初的MVC框架出了什么問題?
在MVC框架初創(chuàng)時, 微軟在現(xiàn)有的ASP.NET平臺上構(gòu)建是合理的, ASP.NET有很多可靠的底層功能, 為開發(fā)過程提供了一個良好的開端, 并已經(jīng)被ASP.NET開發(fā)者所熟知.
但為了將MVC框架移植到最初為Web Forms設(shè)計的平臺上, 需要作出妥協(xié). MVC框架開發(fā)者逐漸習(xí)慣了使用配置文件和微調(diào)代碼才能使應(yīng)用程序正確運(yùn)行, 盡管這些和他們的web應(yīng)用毫無關(guān)系.
隨著MVC框架越來越流行, 微軟開始將一些核心特性加入到Web Forms, 結(jié)果越來越奇怪.
原本用于支持MVC框架的設(shè)計原則被擴(kuò)展, 以支持Web Forms, 他們之間必須能夠很好地融合. 同時, 微軟開始擴(kuò)展ASP.NET, 一般提供創(chuàng)建web服務(wù)(web api)和實(shí)時通訊(SignalR)的新框架. 每一個新框架都加入了自己的配置和開發(fā)約定, 都有自己的優(yōu)點(diǎn)和古怪, 使得整個ASP.NET越來越混亂.

?了解ASP.NET Core
在2015年, 微軟宣布了ASP.NET和MVC框架的新方向, 最終產(chǎn)生了ASP.NET Core MVC, 本書的主要內(nèi)容.
ASP.NET Core基于.NET Core上, .NET Core是.NET框架的跨平臺版本. Windows仍然是一個占據(jù)統(tǒng)治地位的操作系統(tǒng), 但承載在云端小容器中的web應(yīng)用的份額正在增加. 通過采用跨平臺的方法, 微軟拓展了.NET的運(yùn)用范圍, 使ASP.NET Core應(yīng)用程序在更廣泛的載體上部署成為可能, 也讓開發(fā)者可以在Linux或macOS上創(chuàng)建ASP.NET Core web應(yīng)用程序.
ASP.NET Core是一個全新的框架. 它更簡單, 更易用, 擺脫了Web Forms的傳統(tǒng). 而且因為它基于.NET Core, 支持在更多的平臺和容器上開發(fā)web應(yīng)用程序.
ASP.NET Core MVC在新的ASP.NET Core平臺上提供了最初的ASP.NET MVC框架的功能. 它集成了先前的Web API的特性, 包括了一種更自然的生成復(fù)雜內(nèi)容的方式, 并且使關(guān)鍵的開發(fā)任務(wù)(如單元測試)更簡單可預(yù)測.

ASP.NET Core MVC 2中的新內(nèi)容
ASP.NET Core MVC 2 發(fā)行版聚焦于整合早期版本中的一些工具和平臺的更改. ASP.NET Core MVC 2需要.NET Core 2, 其擴(kuò)充了許多API, 并支持更多的Linux發(fā)行版. 有用的更新包括一個簡化了NuGet包管理的新的包管理系統(tǒng), 一個新的ASP.NET Core配置系統(tǒng), 以及對Entity Framework Core 2的支持. 最大的新特性是Razor Pages, 嘗試用更現(xiàn)代的平臺來重建Web頁面的開發(fā)風(fēng)格, 但MVC開發(fā)人員對Razor Pages并不感興趣(我在書中也沒有描述).

ASP.NET Core MVC的關(guān)鍵優(yōu)勢
接下來的章節(jié)簡要的描述新的MVC平臺如何超越傳統(tǒng)的Web Forms和原始的MVC架構(gòu), 它又如何使ASP.NET重新回到前沿.

MVC架構(gòu)
ASP.NET Core MVC遵循MVC模式, 它指導(dǎo)了ASP.NET web應(yīng)用程序的形成和內(nèi)部組件之間的交互.
區(qū)分MVC架構(gòu)模式和ASP.NET Core MVC實(shí)現(xiàn)非常重要. MVC模式不是新鮮事物——可以追溯到1978年在Xerox PARC上的Smalltalk項目——但現(xiàn)在由于以下理由成為受歡迎的web應(yīng)用設(shè)計模式:
MVC模式應(yīng)用的UI遵循一個自然循環(huán): 用戶執(zhí)行一個操作, 應(yīng)用程序更改數(shù)據(jù)模型的狀態(tài)并向用戶更新視圖作為響應(yīng), 然后再次執(zhí)行此循環(huán). 這可以很方便地適應(yīng)傳遞一系列HTTP請求和響應(yīng)的web應(yīng)用程序
Web應(yīng)用程序需要結(jié)合多種技術(shù)(例如數(shù)據(jù)庫, HTML和可執(zhí)行代碼), 通常分為多層. 從這些層的組合中產(chǎn)生的模式可以很自然地映射到MVC模式的概念上.
ASP.NET Core MVC實(shí)現(xiàn)了MVC模式, 相較Web Forms在概念分離方面有極大的提升. 事實(shí)上, ASP.NET Core MVC實(shí)現(xiàn)了各種各樣的特別適合Web應(yīng)用程序的MVC模式.

可擴(kuò)展性
ASP.NET Core和ASP.NET Core MVC是作為一系列具有良好定義的特性的獨(dú)立組件構(gòu)建的, 其實(shí)現(xiàn).NET接口, 或者構(gòu)建在抽象類上. 你可以輕松地將關(guān)鍵組件替換為自己實(shí)現(xiàn)的組件. 一般來說ASP.NET Core為每個組件提供了三個選項:
使用組件的默認(rèn)實(shí)現(xiàn)(足夠應(yīng)對大多數(shù)應(yīng)用程序)
使用默認(rèn)實(shí)現(xiàn)的子類來調(diào)整其行為
使用接口或抽象基類的實(shí)現(xiàn)來完全替換組件

HTML和HTTP的嚴(yán)格控制
ASP.NET Core MVC提供了符合標(biāo)準(zhǔn)的HTML標(biāo)記. 它內(nèi)置的標(biāo)記助手提供符合標(biāo)準(zhǔn)的輸出, 和Web Forms相比有一個重大的改變. ASP.NET Core MVC鼓勵使用CSS來設(shè)計簡潔優(yōu)雅的標(biāo)記, 而不是生成一些幾乎不受控制的HTML.
當(dāng)然, 如果你想為復(fù)雜的UI元素(如日期選擇器或級聯(lián)菜單)添加一些現(xiàn)成的組件, ASP.NET Core MVC采用的”無特殊需求”方法使得引用一些單項優(yōu)勢(best-of-breed)的前端庫(如jQuery, Angular, React或Bootstrap)很簡單. ASP.NET Core MVC與這些庫匹配得很好, 以致于微軟專門創(chuàng)建了預(yù)包含它們的開發(fā)模版.

可測試性
ASP.NET Core MVC架構(gòu)為應(yīng)用程序的可維護(hù)性和可測試性提供了良好開端, 因為你可以自然地將不同的應(yīng)用程序分成獨(dú)立的部分. 另外, ASP.NET Core平臺和MVC框架的每個部分都可以被隔離并進(jìn)行單元測試. 可以使用任意的開源測試框架來進(jìn)行單元測試.
在這本書中, 你會看到一些例子, 如何為ASP.NET MVC控制器編寫簡潔的單元測試, 如何使用各種策略以及進(jìn)行模擬操作. 即使你從未寫過單元測試, 也會有一個很好的開始.
可測試性不僅僅包含單元測試. ASP.NET Core MVC應(yīng)用程序也可以和UI自動化測試工具一起工作. 你可以編寫模擬用戶交互的測試腳本, 而不需要猜測框架將生成那些HTML元素結(jié)構(gòu), CSS類或ID, 也不需要擔(dān)心結(jié)構(gòu)的意外變化.

強(qiáng)大的路由系統(tǒng)
由于web應(yīng)用程序技術(shù)的發(fā)展, URL風(fēng)格也發(fā)生了演變. 類似/App_v2/User/Page.aspx?action=show%20prop&prop_id=82742的URL逐漸被簡單的類似/to-rent/chicago/2303-silver-street的URL取代.
關(guān)注URL結(jié)構(gòu)的理由很多:
搜索引擎為URL中的關(guān)鍵字賦予權(quán)重. 搜索
rent in Chicago更容易出現(xiàn)簡單的URL許多網(wǎng)絡(luò)用戶已經(jīng)足夠了解URL, 并可以通過在瀏覽器的地址欄中輸入URL來進(jìn)行導(dǎo)航
當(dāng)人們理解URL的含義時, 更容易點(diǎn)擊它, 與朋友分享, 甚至在電話中朗讀.
不會暴露應(yīng)用程序的技術(shù)細(xì)節(jié)文件夾和文件名結(jié)構(gòu), 因此可以自由更改底層實(shí)現(xiàn), 而不會破壞傳入鏈接.
早期的框架很難實(shí)現(xiàn)干凈的URL, 但ASP.NET Core MVC默認(rèn)使用稱為URL router的功能來提供干凈的URL. 這使你可以控制URL結(jié)構(gòu)和應(yīng)用程序的關(guān)系, 自由創(chuàng)建有意義的URL模式, 而不需要遵循預(yù)定義的模式. 當(dāng)然, 這意味著你可以輕松地定義現(xiàn)代的REST風(fēng)格URL結(jié)構(gòu).?

現(xiàn)代的API
微軟的.NET平臺在每個發(fā)行版中不斷發(fā)展, 支持甚至引領(lǐng)最新的現(xiàn)代編程趨勢. ASP.NET Core MVC是為.NET Core構(gòu)建的, 因此它的API可以充分利用C#開發(fā)者熟悉的語言特性, 包括await關(guān)鍵字, 擴(kuò)展方法, lambda表達(dá)式, 匿名和動態(tài)類型, LINQ. 許多ASP.NET Core MVC API方法和編碼模式比早期版本更清晰, 更具表現(xiàn)力. 如果你不熟悉最新的C#語言特性, 請不要擔(dān)心, 我們在第四章中總結(jié)了MVC開發(fā)中最重要的C#特性.

跨平臺
之前的ASP.NET版本局限于Windows平臺, 需要在Windows桌面版上編寫web應(yīng)用, 并部署和運(yùn)行在Windows server上. 微軟讓ASP.NET Core的開發(fā)和部署跨平臺化了. .NET Core在不同平臺都可以獲取, 包括macOS和大量流行的Linux發(fā)行版. 跨平臺支持使得ASP.NET Core應(yīng)用更容易部署, 也很好地支持了應(yīng)用容器平臺, 如Docker.
現(xiàn)在大多數(shù)ASP.NET Core MVC開發(fā)都將是使用Visual Studio完成的, 但微軟也創(chuàng)建了跨平臺的開發(fā)工具Visual Studio Code, 意味著ASP.NET Core開發(fā)不局限于Windows了.

ASP.NET Core MVC是開源的
不像微軟之前的web應(yīng)用開發(fā)平臺, 你可以免費(fèi)下載ASP.NET Core和ASP.NET Core MVC的源碼, 甚至編譯自己定制的版本. 當(dāng)你在調(diào)試系統(tǒng)組件并想逐步調(diào)試其代碼(甚至閱讀程序員的原始注釋)時, 這是非常寶貴的. 如果你正在構(gòu)建高級組件, 并希望了解存在哪些開發(fā)可能性, 或內(nèi)置組件實(shí)際如何工作時, 也是很有用的. 你可以在https://github.com/aspnet下載ASP.NET Core和ASP.NET Core MVC的源碼.

總結(jié)
在這一章中, 我解釋了ASP.NET Core MVC存在的背景, 和它從Web Forms和最初的ASP.NET MVC的演變. 我描述了使用ASP.NET Core MVC的好處和這本書的結(jié)構(gòu). 在下一章中, 你將看到ASP.NET Core MVC的一個簡單示例, 來展示這些優(yōu)越特性.
往期推薦
某程序員動了公司的祖?zhèn)鞔a“屎山”,半年后怒交辭職報告!
為什么.NET Web 應(yīng)用推薦使用 await、async異步編程?

