ASP.NET MVC是一個建立在ASP.NET平臺上基于MVC模式的Web開發框架,它提供了一種與Web Form完全不同的開發方式。ASP.NET Web Form借鑒了Windows Form基于控件和事件注冊的編程模式,使Web應用的開發變得簡單而快捷,但是它卻使開發人員與Web的本質漸行漸遠。ASP.NET MVC是一種回歸,它使開發人員可以真正地面向Web進行編程,我們面對的不再是拖拉到Web頁面的控件,而是整個HTTP請求和響應的流程。
這不是一本傳統意義上的入門書籍
在《ASP .NET MVC 4框架揭秘》出版之后,讀者通過多種渠道將他們對本書的看法、建議和意見反饋給筆者。有一些讀者覺得本書對他們來說太“深”了,因為他們希望買到的是一本單純的入門書籍,所以我不得不再次強調——“這不是一本傳統意義上的入門書籍”。如果你之前根本沒有接觸過ASP.NET MVC,并且希望有一本書能夠讓你在一兩個星期內掌握ASP.NET MVC 的基本編程模式,那么筆者覺得選擇本書并不是明智的。
筆者個人認為掌握ASP.NET MVC具有3個層次。了解基本的編程模式,掌握Controller和View的定義方式,知道路由如何注冊及驗證規則如何定義,此為第一層次。第二層次要求我們對ASP.NET MVC框架本身從請求接收到響應回復的整個流程有一個清晰的認識,這包括請求如何被路由、目標Controller如何被激活、Model元數據如何被解析、Action方法如何被執行、View如何呈現等。ASP.NET MVC本身是一個極具可擴展的開發框架,合理利用其擴展性可以解決很多開發中的實際問題,而掌握ASP.NET MVC的最高層次就是憑著對框架本身的運行機制的了解準確地找到相應的擴展點,并創建相應的擴展來解決我們遇到的問題。
本書不是一本ASP.NET MVC入門書籍,而是一本讓處于第一層次的讀者快速進入第二和第三層次的書。如果你具有進入更高層次的需求,并且有充裕的時間來閱讀,筆者堅信你一定能夠通過此書獲得其他同類書籍難以提供的東西。
不少人覺得本書過于“深入”,但筆者個人寧愿說本書“走得更遠”。雖然本書比其他同類書籍更加近距離地觸摸到了ASP.NET MVC 框架的內核,但就其內容本身來說,筆者認為本書并沒有什么“深不可測”的東西。盡管本書不是一本純粹意義上的入門書籍,但是筆者絕不會根據讀者個人的技術水平將其排除在本書的讀者范圍之外。如果讀者具有基本的.NET方面的知識儲備,并且從事過簡單的Web開發,閱讀本書不會有太大的障礙。
這是一本講述ASP.NET MVC框架本質的書
很多.NET開發人員都在抱怨微軟開發技術過快的更新頻率讓他們無所適從,其實他們看到的只是單純的版本升級而已,一些本質的東西一直是“穩定”的。微軟推出.NET戰略已經十多年了,CLR卻只有4個版本而已。最新版本的ASP.NET雖然表面上已經看不到太多最初的影子,但是整個請求處理的管道一直未曾改變。對于一項開發技術,只要我們了解了它最根本性的一些東西,不但不應該懼怕其高頻率的版本更替,而應該熱烈擁抱它。本書力求將關于ASP.NET MVC框架最根本的東西帶給大家,而不是羅列一些簡單的編程技巧。
這本書與《ASP .NET MVC 4框架揭秘》有何不同
本書針對最新版本的ASP.NET MVC ,所以ASP.NET MVC 5提供的新特性和對ASP.NET MVC 4現有特性的改變自然體現在本書之中。通過微軟“官方”渠道發布的信息我們知道,“特性路由”和“認證過濾器”是ASP.NET MVC 5提供的兩個新特性,我們在本書中會通過單獨的章節(第13章“特性路由”)來對特性路由作詳細講解,針對認證過濾器的介紹則放到新增加的一章(第12章“過濾器”)中。
除了這些通過官方渠道了解到的改變之外,其實微軟在ASP.NET MVC 5框架內部作了很多的改進,這些東西只有當我們深入去分析其源碼時才有可能發現。這些“不為人知”的內容也包含在本書之中,如果你手中正好有一本《ASP.NET MVC 4框架揭秘》,在閱讀的時候對照一下就知道了。
本書除了反映ASP.NET MVC 5本身的改變之外,還對前版一些遺漏掉的知識點進行了補充。為了讓讀者更好地理解本書的內容并盡可能地迎合大多數人的思維方式,我們在寫作過程中對整本書的結構作了調整,同時對一些表達方式作了相應的改變。
和大部分ASP.NET MVC的書籍一樣,《ASP.NET MVC 4框架揭秘》利用一個單獨的章節來介紹Web API,這種做法實際上給很多讀者造成了一種誤解,讓他們覺得ASP.NET Web API僅僅是ASP.NET MVC的附屬產品。實際上兩者不但在運行上使用不同的消息處理管道,并且這兩個管道在設計上也是截然不同的,所以本書中找不到任何關于ASP.NET Web API的內容。如果你希望深入系統地學習ASP.NET Web API,可以考慮本書的姊妹篇《ASP.NET Web API 2框架揭秘》。
這是一本實用的書嗎?
可能有人覺得這本剖析ASP.NET MVC框架運行原理的書沒有什么“實際”的意義,因為我們每天的日常工作就是編程,知道了ASP.NET MVC從請求接收到響應回復之間整個處理流程并不會對我們的工作造成實質性的改變,這是一種極端錯誤的想法。學習一種軟件開發技術就像是練一門功夫,不僅要苦練攻敵招式,還得研習內功心法。編程模式是攻敵招式,框架背后的設計原理是內功心法,沒有內功心法支撐的招式只能是花拳繡腿,而具有極高內功修為的高手卻能“無招勝有招”。
除此之外,由于我們編寫的程序最終是在ASP.NET MVC框架上運行的,程序的高效性決定了它是否能夠最大限度地“迎合”框架的運行機制,所以了解ASP.NET MVC框架的運行原理有利于我們寫出高質量的程序。
很多讀者都問筆者為何有那么多時間和精力去深入學習多個不同的開發框架(比如WCF、ASP.NET MVC和ASP.NET Web API等),其實這和從事的工作有關。多年以來,筆者在公司所作的工作就是設計、開發和維護一套內部的開發框架,這個框架的根本目的在于讓我們可以采用一種類似于流水線的項目開發方式,不僅可以提高開發效率,還能提高項目本身的質量并降低對最終開發人員的技能要求,實現的途徑就是讓最終的開發人員只關心具體業務功能的實現,所有非業務功能都由框架本身來完成。
為了完成這個使命,我們針對.NET平臺上的開發技術作了很多擴展。為了能夠精準地定位采用的擴展點,我們不得不對開發技術本身有一個深刻的認識,所以深入學習.NET平臺主流開發技術是筆者的本質工作之一。為了將這些實用的擴展服務于大眾,筆者將這些擴展放到了相關的書籍之中。筆者自然不會將我們做的東西直接共享出來(因為這是違法的),所以書中涉及的這些擴展都經過刻意簡化,因為筆者希望的不是讓讀者直接使用這些擴展,而是根據其體現出來的原理來設計你們需要的擴展。
ASP.NET MVC之外的一些東西
在筆者的周圍存著這樣的一些人,他們以剛畢業一兩年的畢業生為主。他們大都工作勤奮、聰明好學,手中經常捧著GoF的《設計模式》,總是希望在將書中的設計模式應用到具體項目之中,或者希望通過項目的實踐來印證他們在書本上的設計模式,但是理論和實踐之間的距離總讓他們感到困惑。
. 要從真實的項目或者產品中學習“實用”的軟件架構設計知識,先得確定目標項目或者產品中采用的架構思想和設計模式是正確的,而我們參與的很多項目其實被“架構”得一塌糊涂。對于像ASP.NET這樣的產品,其基礎架構能夠在很長一段時間內保持不變,本身就證明了應用在上面的架構設計的正確性,它們不正是我們學習架構設計最好的素材嗎?本書對ASP.NET MVC框架的運行機制進行了深入剖析,實際上是將ASP.NET MVC的整個設計展示在讀者面前,讀者也許可以將本書作為一本“架構設計”的書來讀。
很多讀者向筆者咨詢針對一種新的開發技術,如何才能更加有效地掌握其“精髓”。這是一個關于學習方法的問題,筆者個人采用的學習方法不可能適用于所有的人。盡管如此,本書也或多或少地體現了筆者個人采用的學習方法,所以在論述某個知識點的時候,不但會告訴讀者“是什么”和“為什么”,還會告訴讀者“如何證明是這樣”。換句話說,筆者不僅僅將某個論點拋給你,還會為你展現整個論證的過程。
本書的寫作特點
和其他同類書籍作者總是從“靜態編程”作為切入點不同,筆者以“動態執行”的視角來審視ASP.NET MVC框架。本書以框架本身處理請求的流程為主線,力求將ASP.NET MVC框架從接收請求到回復響應的整個流程完整而清晰地展現在讀者面前。在本書的第1章中,我們設計了一個“迷你版”的ASP.NET MVC框架,其目的在于讓讀者能夠對ASP.NET MVC的執行管道有一個整體的認識,至于組成這個管道的每個環節,則通過后續的章節對其架構設計進行詳細介紹,對其執行原理進行深入剖析。
本書具有一個與其他中文原創或者翻譯書籍截然不同的特點,那就是幾乎所有的術語都采用英文,比如Controller、Action和Model在本書中并沒有翻譯成中文“控制器”、“操作”和“模型”。因為筆者認為很多術語其實很難找到一個語義完全等同的中文詞組或短語與之對應,對于習慣了英文作為“開發語言”的讀者來說,強行翻譯其實是不必要的。
除此之外,這不是一本純理論的書,而是一本“實證型”的書,在書中提供了一百多個可供單獨下載的實例演示。這些實例在本書中具有不同的作用,有的是為了探測和證明對應的論點,有的是為了演示某種實用的編程技巧。
目錄
第1章 asp.net + mvc 1
1.1 傳統mvc模式 2
1.1.1 自治視圖 2
1.1.2 什么是mvc模式 3
1.2 mvc的變體 4
1.2.1 mvp 5
1.2.2 model 2 13
1.2.3 asp.net mvc與model 2 15
1.3 iis/asp.net管道 15
1.3.1 iis 5.x與asp.net 16
1.3.2 iis 6.0與asp.net 17
1.3.3 iis 7.0與asp.net 19
1.3.4 asp.net集成 20
1.3.5 asp.net管道 22
1.4 asp.net mvc是如何運行的 28
1.4.1 建立在“迷你版”asp.net mvc上的web應用 28
1.4.2 路由 31
1.4.3 controller的激活 37
1.4.4 action的執行 41
1.4.5 完整的流程 49
第2章 路由 51
2.1 asp.net路由 52
2.1.1 請求url與物理文件的分離 52
2.1.2 實例演示:通過路由實現請求地址與.aspx頁面的映射(s201) 53
2.1.3 route與routetable 57
2.1.4 路由注冊 65
2.1.5 根據路由規則生成url 77
2.2 asp.net mvc路由 79
2.2.1 路由映射 79
2.2.2 路由注冊(s210) 80
2.2.3 缺省url參數 83
2.2.4 基于area的路由映射 85
2.2.5 鏈接和url的生成 91
2.3 動態httphandler映射 98
2.3.1 urlroutingmodule 99
2.3.2 pageroutehandler與mvcroutehandler 100
2.3.3 asp.net路由系統擴展 101
2.3.4 實例演示:通過自定義route對asp.net路由系統進行擴展(s214) 102
第3章 controller的激活 107
3.1 controller激活系統全景展示 108
3.1.1 controller 108
3.1.2 controllerfactory 114
3.1.3 controllerbuilder 115
3.1.4 controller的激活與路由 122
3.2 controller默認激活機制 125
3.2.1 controller類型的解析 125
3.2.2 controller類型的緩存 130
3.2.3 controller的釋放和會話狀態行為的控制 131
3.3 ioc的應用 133
3.3.1 從unity來認識ioc 133
3.3.2 controller與model的解耦 135
3.3.3 基于ioc的controllerfactory 137
3.3.4 基于ioc的controlleractivator 143
3.3.5 基于ioc的dependencyresolver 145
第4章 model元數據的解析 149
4.1 model元數據 150
4.1.1 model元數據層次化結構 150
4.1.2 model元數據的定制 154
4.1.3 imetadataaware接口 171
4.2 模板化數據的呈現 176
4.2.1 實例演示:通過模板將布爾值顯示為radiobutton(s409) 176
4.2.2 預定義模板 178
4.2.3 針對數據類型的模板 185
4.2.4 數據類型名稱 v.s. 模板名稱 189
4.2.5 模板的獲取與執行 193
4.2.6 實例演示:通過定制model元數據和自定義模板 實現預定義列表的呈現(s412)197
4.3 model元數據的提供機制 205
4.3.1 再談modelmetadata 206
4.3.2 modelmetadataprovider 210
4.3.3 model元數據提供系統的擴展 214
第5章 3個重要的描述對象 217
5.1 controllerdescriptor 218
5.1.1 reflectedcontrollerdescriptor 219
5.1.2 reflectedasynccontrollerdescriptor 228
5.2 actiondescriptor 229
5.2.1 asyncactiondescriptor 230
5.2.2 reflectedactiondescriptor 231
5.2.3 reflectedasyncactiondescriptor 232
5.2.4 taskasyncactiondescriptor 233
5.3 parameterdescriptor 234
第6章 model的綁定(一) 236
6.1 源數據的提供 237
6.1.1 namevaluecollectionvalueprovider 238
6.1.2 dictionaryvalueprovider 246
6.1.3 valueproviderfactory 254
6.1.4 valueproviderfactories 255
6.2 modelbinder及其提供策略 259
6.2.1 modelbinder 259
6.2.2 modelbinderprovider 265
6.2.3 modelbinders 268
6.2.4 custommodelbinderattribute 271
6.2.5 針對參數的modelbinder是如何創建的 274
6.3 model綁定的實施 276
6.3.1 綁定上下文的初始化 277
6.3.2 綁定過程中對modelstate的設置 279
第7章 model的綁定(二) 283
7.1 綁定簡單對象 284
7.1.1 利用valueprovider綁定簡單對象 284
7.1.2 實例演示:利用mydefaultmodelbinder綁定簡單類型參數(s701) 286
7.2 綁定復雜對象 289
7.2.1 復雜對象層次化結構 289
7.2.2 遞歸式綁定 291
7.2.3 實例演示:利用mydefaultmodelbinder綁定復雜類型參數(s702、s703) 294
7.3 綁定集合 297
7.3.1 針對同名數據項的集合綁定 297
7.3.2 針對索引的集合綁定 302
7.4 綁定字典 311
7.4.1 字典是一個復雜類型的集合 311
7.4.2 針對字典類型的model綁定策略 312
7.4.3 實例演示:利用mydefaultmodelbinder綁定字典類型參數(s707) 316
第8章 model的驗證(一) 318
8.1 幾種參數驗證方式 319
8.1.1 modelerror 319
8.1.2 驗證消息的呈現 320
8.1.3 手工驗證綁定的參數 322
8.1.4 使用validationattribute特性 327
8.1.5 讓數據類型實現ivalidatableobject接口 330
8.1.6 讓數據類型實現idataerrorinfo接口 332
8.2 modelvalidator及其提供策略 334
8.2.1 modelvalidator與modelvalidatorprovider 334
8.2.2 dataannotationsmodelvalidator 337
8.2.3 validatableobjectadapter 337
8.2.4 dataerrorinfomodelvalidator 338
8.2.5 clientmodelvalidator 339
8.2.6 compositemodelvalidator 341
8.3 model驗證的實施 345
8.3.1 model綁定過程中的驗證 346
8.3.2 實例演示:模擬model綁定中的驗證(s810) 347
8.3.3 針對“必需”數據成員的驗證 351
第9章 model的驗證(二) 354
9.1 validationattribute特性 355
9.1.1 數據是如何被驗證的 356
9.1.2 幾個常用的validationattribute 358
9.1.3 應用validationattribute特性的唯一性 360
9.2 dataannotationsmodelvalidator及其提供策略 364
9.2.1 “適配”型dataannotationsmodelvalidator 365
9.2.2 dataannotationsmodelvalidatorprovider 368
9.2.3 將validationattribute特性應用到參數上 375
9.2.4 一種model類型,多種驗證規則 382
9.3 客戶端驗證 389
9.3.1 jquery驗證 390
9.3.2 基于jquery的model驗證 394
9.3.3 自定義驗證 398
第10章 action方法的執行 402
10.1 異步action的定義 403
10.1.1 基于線程池的請求處理機制 403
10.1.2 兩種異步action方法的定義 404
10.1.3 asyncmanager 406
10.2 各種同步與異步組件 412
10.2.1 mvchandler 412
10.2.2 controller 413
10.2.3 actioninvoker 414
10.2.4 controllerdescriptor 420
10.2.5 actiondescriptor 423
10.3 目標方法的執行 430
10.3.1 action方法并不以“反射”方式執行 430
10.3.2 實例演示:采用針對表達式樹執行action方法(s1010) 432
第11章 view的呈現 437
11.1 actionresult 438
11.1.1 emptyresult 438
11.1.2 contentresult 439
11.1.3 fileresult 446
11.1.4 javascriptresult 451
11.1.5 jsonresult 455
11.1.6 httpstatuscoderesult 457
11.1.7 redirectresult/redirecttorouteresult 458
11.2 viewresult與viewengine 461
11.2.1 view引擎中的view 461
11.2.2 viewengine 463
11.2.3 viewresult的執行 465
11.3 razor引擎 474
11.3.1 view的編譯原理 475
11.3.2 webviewpage與webviewpage[tmodel] 480
11.3.3 razorview 485
11.3.4 razorviewengine 495
第12章 過濾器 499
12.1 filter及其提供機制 500
12.1.1 filter與filterprovider 500
12.1.2 以特性方式注冊過濾器 502
12.1.3 controller本身就是過濾器 504
12.1.4 過濾器的全局注冊 504
12.1.5 實例演示:驗證filter的提供機制和執行順序(s1201,s1202,s1203) 506
12.2 authenticationfilter 511
12.2.1 authenticationfilter的執行流程 512
12.2.2 實例演示:通過自定義authenticationfilter實現basic認證(s1204) 513
12.3 authorizationfilter 518
12.3.1 authorizeattribute 518
12.3.2 requirehttpsattribute 520
12.3.3 validateinputattribute 520
12.3.4 validateantiforgerytokenattribute 523
12.3.5 childactiononlyattribute 527
12.4 actionfilter 528
12.4.1 actionfilter的執行流程 529
12.4.2 actionfilter對actionresult的設置 530
12.4.3 異常處理 532
12.5 exceptionfilter 534
12.5.1 handleerrorattribute 535
12.5.2 實例演示:利用自定義的exceptionfilter集成enterprise library進行異常處理(s1207, s1208, s1209) 537
12.6 resultfilter與overridefilter 551
12.6.1 resultfilter的執行流程 552
12.6.2 屏蔽外圍過濾器 553
第13章 特性路由 556
13.1 特性路由注冊 557
13.1.1 routeinfoprovider特性 557
13.1.2 基本路由映射 558
13.1.3 讓路由模板能夠盡可能反映資源的層次結構 559
13.1.4 為路由變量設置約束 560
13.1.5 缺省路由變量 561
13.1.6 設置模板前綴 562
13.1.7 設置area名稱 563
13.2 約束表達式的解析 564
13.2.1 rangerouteconstraint 565
13.2.2 inlineconstraintresolver 566
13.2.3 自定義約束 570
13.3 route的創建 574
13.3.1 特性路由注冊的route對象 574
13.3.2 route的生成機制 579
13.3.3 controller的激活與action方法的選擇 579
第14章 案例實踐 581
14.1 功能簡介 582
14.1.1 商品列表的呈現 582
14.1.2 訂購商品 584
14.1.3 登錄與錯誤頁面 585
14.2 設計概述 586
14.2.1 controller-service-repository 586
14.2.2 ioc的應用 591
14.2.3 aop的應用 594
14.2.4 異常處理 601
14.3 編程實現 602
14.3.1 數據表的創建 603
14.3.2 repository 604
14.3.3 service 609
14.3.4 路由注冊和布局 612
14.3.5 productcontroller 616
14.3.6 ordercontroller 624
14.3.7 accountcontroller 630
文章列表