這也給了我一個經驗。一個.NET Framework版本的升級的「發行記錄」,我想,沒幾個人會去全部看完,因為更新的內容非常的龐大,所以我是挑著看,但也養成的壞習慣。.NET Framework有推出「多目標管理」,也就是說,還是以當前「目標」選擇一個「正確」的「版本」才是正解,這樣不管在未來維護、除錯…才能減少不必要的複雜度。另一個重點是,.NET Framework向下相容做的很不錯,這種非.NET Framework版本的升級跟.NET Framework不太一樣,一般而言,你可以在.NET Framework 4.0下寫.NET Framework 2.0 / 3.0 / 3.5都不會出錯,這又養成另一壞習慣。
反正為了減少「自我感覺良好」的笑話,還是鞭策自己一下,"等"也不會更好。以下以「ASP.NET MVC 3 Overview」為基礎半翻譯結果,文件中還有許多Blog等資料,就盡力而為,先把應該了解的內容搞清楚再說。再以「ASP.NET MVC 3 Release Notes」加強就差不多了。
ASP.NET MVC 3 概觀
它就是一份重點整理了,所以看它最快。MVC和一些重點英文單字,我就不使用中文,怪怪的。如有翻譯不當的情況,請指教。Razor View Engine
ASP.NET MVC 3新增一個全新的檢視引擎(view engine),稱呼為「Razor(剃刀)」。Razor的優勢
- Razor 語法簡潔有力。
- Razor 簡單學習。
- 與 IntelliSense 整合。
- Razor 的頁面(Views)可進行單元測試。
- @model 語法能傳遞詳細的型別給View。
- @* *@ 註解語法。
- 能定義預設值(像是 layoutpage )。
- Html.Raw() 方法能顯示文字而不進行HTML編碼。
- 支援分享程式碼在多個Views(_viewstart.cshtml or _viewstart.vbhtml檔案)之間。
- Chart. 轉譯出圖表。
- WebGrid. 轉譯出資料表,含排序與分頁。
- Crypto. 使用雜湊演算法產生嚴謹的雜湊密碼。
- WebImage. 轉譯出圖片。
- WebMail. 傳送Email。
更多關於Razor的資訊,請參考:
以行銷術語來說,Razor提供的簡潔語法與HTML Helper是二大亮點,我們可以打更少鍵盤實現更多的功能,以前我們要自己實作一堆程式碼才能有的功能,現在透過Razor view engine就直接提供給我們。但可惜的是,使用Webform view engine(*.aspx)就無法使用以上HTML helper。為什麼不一起實作呢???支援多檢視引擎(Multiple View Engines)
在我們新增ASP.NET MVC 3專案時,就可以讓你選擇是否使用新的Razor view engine或預設的view engine(ASPX),另外,你也可以使用open source的view engine如Spark、NHaml、NDjango…等。Controller 改善
全域動作過濾器(Global Action Filters)
在Action方法之前及之後執行邏輯規則程式碼,在ASP.NET MVC 2提供了動作過濾器(Action Filters)。在ASP.NET MVC 3更提供一個全域過濾器(Global Filters)來加入它們到一個 GlobalFilters 集合中。在Global.ascx新增一個Sub來進行Global Filters註冊動作:
Shared Sub RegisterGlobalFilters(ByVal filters As GlobalFilterCollection) filters.Add(New HandleErrorAttribute()) End Sub
在ASP.NET MVC 2必須在Controller註冊<HandleError()>屬性,在ASP.NET MVC 3的Global Filters的註冊之後,就不必在Controller裡再註冊<HandleError()>屬性了。
更多全域動作過濾器資訊,請參考:
新ViewBag屬性
在ASP.NET MVC 2支援 ViewData 屬性能讓你傳遞資料到View頁面。在ASP.NET MVC 3另供了一個 ViewBag 屬性來進行相同目的,例如:原先是使用「ViewData("Message") ="歡迎使用 ASP.NET MVC!"」,現在你能使用「ViewBag.Message = "歡迎使用 ASP.NET MVC!"」來替代。你在使用ViewBag屬性時,不需要去定義任何強型別類別,因為他是一個動態(dynamic)屬性,你在設定或取得屬性時,它能在執行時動態解析它們。在內部,ViewBag屬性將資料儲存在name/value的 ViewData 字典中。(在ASP.NET MVC 3的預覽版本中,這個屬性被稱為ViewModel)
Public ReadOnly Property ViewBag As Object Get
新ActionResult型別
在ASP.NET MVC 3新增及增強ActionResult。- HttpNotFoundResult
(新增)傳回 404 HTTP狀態碼。 - HttpStatusCodeResult
(新增)傳回使用者指定HTTP狀態碼。 - RedirectResult
(增強) 依Boolean參數來決定傳回一個暫時重導向(302 HTTP狀態碼)或是永久重導向(301 HTTP狀態碼)。結合這個改變,Controller類別提供了三個方法來支持永久重導向:RedirectPermanent、RedirectToRoutePermanent、RedirectToActionPermanent。這些方法會回傳一個 Permanent 屬性為 True 的 RedirectResult 的執行個體(instance)。
JavaScript和Ajax 改善
預設下,ASP.NET MVC 3 中的 Ajax 和驗證輔助方法使用無侵入式(unobtrusive)的JavaScript。無侵入式JavaScript會避免在HTML中插入行內(inline)的JavaScript,這使用HTML更精簡和更少干擾,也使得更加容易被替換和自訂JavaScript函式庫。在ASP.NET MVC 3的驗證輔助方法預設使用 jQueryValidate 外掛。如果你希望使用 ASP.NET MVC 2的行為,你可在 web.config 中調整設定來關閉無侵入式JavaScript。<appSettings> <add key="ClientValidationEnabled" value="true"/> <add key="UnobtrusiveJavaScriptEnabled" value="true"/> </appSettings>
將UnobtrusiveJavaScriptEnabled改為False即可關閉。更多Javascript和Ajax改善的資訊,請參考:
- Basic introduction to unobtrusive JavaScript on the Wikipedia site
- Brad Wilson's Unobtrusive JavaScript Post
- Brad Wilson's Unobtrusive JavaScript Validation Post
- Creating a MVC 3 Application with Razor and Unobtrusive JavaScript (tutorial on the ASP.NET site)
- ASP.NET MVC 2與MVC 3使用AjaxHelper引用Javascript檔不同(自我感覺良好就是它)
客戶端驗證(Clinet-Side Validation),預設修改為「啟用」
在先前版本的MVC中,你需要明確地在View中去呼叫 Html.EnableClientValidation 方法來啟用客戶端驗證。在ASP.NET MVC 3中已經不再需要,因為預設就會啟用客戶端驗證。我們能在 web.config 裡關閉此設定。<appSettings> <add key="ClientValidationEnabled" value="true"/> <add key="UnobtrusiveJavaScriptEnabled" value="true"/> </appSettings>
將 ClientValidationEnabled 改為 False 即可關閉。
別外,為了使客戶端驗證能正常作業,你仍然需要在網站中加入 jQuery 和 jQuery.Validation 函式庫的參考。你能從自己的網站中提供它們,或是使用 Microsoft 或 Google 的 CDN (content delivery network ) 服務。
遠端驗證者(Remote Validator)
ASP.NET MVC 3 新增一個 RemoteAttribute 類別來對 jQuery Validation 外掛的遠端驗證提供支援。此支援讓客戶端驗證函式庫能自動呼叫一個你定義在伺服器端的自訂方法,且只能在伺服器端上完成的驗證邏輯。在下面範例中,Remote 屬性指定用戶端驗證透過一個定義在 UserController 類別中名為 UserNameAvailable 的方法來驗證用戶名稱欄位。
Public Class User ' <remote("actionname", "controllername")> <remote("usernameavailable", "users")> Public Property UserName() As String End Class
以下是對應的Controller及Action:
Public Class UsersController Inherits System.Web.Mvc.Controller Public Function UserNameAvailable(username As String) As Boolean If MyRepository.UserNameExists(username) Then Return False End If Return True) End Function End Class
其他 Remote 屬性資訊請參考MSDN:How to: Implement Remote Validation in ASP.NET MVC
JSON繫結(Binding)支援
ASP.NET MVC 3內建了對JSON繫結的支援,允許 Action 方法接收 JSON 編碼的資料,而且模型繫結(Model-bind)到Acion的參數。這個特色常被用於客戶端的樣板和資料繫結中。客戶端樣板能讓你格式化和顯示一個或多個的資料項目,ASP.NET MVC 3讓你簡單的連接客戶端樣版和伺器端的Action方法,透過JSON來發送和接收資料。更多JSON繫結資訊請參考「JavaScript和Ajax 改善」一節在Scott Guthrie's MVC 3 Preview blog post。Model驗證改善
"DataAnnotation" Metadata屬性
ASP.NET MVC 3支援 DataAnnotations 的中繼資料(metadata)屬性,像是 DisplayAttribute。"ValidationAttribute"類別
在 .NET Framework 4 改善了 ValidationAttribute 類別,支援了新的 IsValid 多載,提供關於當下驗證的整體背景資訊,像是什麼物件被驗證了。這讓你能基於 Model 的其他屬性來驗證當前的值。例如,新的 CompareAttribute 屬性讓你能比較 Model 中兩個屬性的值。在下面範例, ComparePassword屬性必須與 Password 欄位相配來同時通過驗證。Public Class UsersController Inherits System.Web.Mvc.Controller <Required> Public Property Password() As String <Required, Compare("Password")> Public Property ComparePassword As String End Class
Validation介面
IValidatableObject 介面讓你能使用Model層級的驗證,且讓你能提供整個Model狀態的驗證錯誤息訊,或在Model的兩個屬性之間。當Model繫結時,ASP.NET MVC 3現在從 IValidatableObject 介面接收錯誤息訊,在View使用內建 HTML helper時,將會自動標識或高亮度強調受影響的範圍。IClientValidatable 介面讓你在ASP.NET MVC在運作時發現支援的客戶端驗證器,這個介面被設計用來支援整合不同的驗證框架。
更多驗證介面的資訊,請參考在Scott Guthrie's MVC 3 Preview blog post的Model驗證改善段落。
相依注入(Dependency Injection,DI)改善
ASP.NET MVC 3提供更好的相依注入(Dependency Injection, DI)和控器反轉(Inversion of Cntrol, IoC)容器支援。在下面區域(Areas)支援DI:控制器:registering and injecting controller factories, injecting controllers。
檢視:registering and injecting view engines, injecting dependencies into view pages。
動作過濾器:locating and injecting filters。
模型繫結:registering and injecting。
模型驗證提供器:registering and injecting。
模型metadata提供器:registering and injecting。
Value 提供器:registering and injecting。
ASP.NET MVC 3 支援 Common Service Locator 函式庫和任何支援這個函式庫的 IServiceLocator 介面的DI容器。它也支援新的容易整合到 DI 框架的 IDependencyResolver介面。
更多關於ASP.NET MVC 3的 DI 資訊,請參考:Brad Wilson's series of blog posts on Service Location
ASP.NET MVC 3其他新功能
NuGet整合
ASP.NET MVC 3會自動安裝和啟用NuGet,NuGet是一個免費開源碼組件管理器,它讓你簡單去尋找和安裝組件,和使用.NET 類別庫和工具在你的專案中。它可以和所有Visual Studio 專案類型一起作業,包含ASP.NET Web Forms(*.aspx)及ASP.NET MVC。NuGet允許開發者維護開源碼專案,(例如,像Moq、NHibernate、Ninject、StructureMap、NUnit、Windsor、RhinoMocks、Elmah…等)可以去注冊它們到一個上線的網站中。讓它是那麼容易讓.NET開發者去使用其中一個函式庫來尋找組件並安裝它們到專案中去研究。
更多關於NuGet的資訊,請參考:NuGet documentation on the CodePlex site。另有一篇暗黑執行緒所寫:還在揮汗徒手安裝程式庫? 試試NuGet吧。
部分頁面的輸出快取
ASP.NET MVC 從版本1 開始支援整個頁面的輸出快取。ASP.NET MVC 3更提供了部分頁面的輸出快取。這讓你容易地輸出快取一個區域或片斷。更多關於快取資訊,Scott Guthrie's blog post on the MVC 3 release candidate 中 Partial Page Output Caching 段落。還有 MVC 3 Release Notes 的 Child Action Output Caching 段落。可參考:MVC 3 Partial Output Cache - Simple Demo(正體中文)
在請求驗證上的粒狀控制(Granular Control)
ASP.NET MVC 內建了請求驗證機制來自動幫助預防跨站攻擊(XSS)和HTML注入攻擊。不管如何,有時你還是希望能明確關閉請求驗證,像是,你想讓使用者能提交含HTML標籤的內容(例如,在一個部落格或內容管理系統(CMS)之中),現在你可透過增加 AllowHtml 屬性到模型(Models)或檢視模型(View Models)來支援在模型繫結時一個屬性關閉請求驗證。更多請求驗證資訊,請參考:Scott Guthrie's blog post on the MVC 3 release candidate 中 Unobtrusive JavaScript and Validation 段落。
延伸"新專案"對話視窗
在ASP.NET MVC 3,你能增加專案樣版,檢視引擎,單元測試專案框架到新專案對話視窗。Scaffolding改善
相較於之前版本的MVC,ASP.NET MVC 3中scaffolding樣板在Model和操作上更為合適,對於識別主鍵屬性提供了更好的支援,例如,scaffolding樣板不的將主鍵加入編輯表單欄位中。預設下,Create和Edit的scaffolding樣板現在使用 Html.EditorFor 輔助方法來替代 Html.TextBoxFor 輔助方法。這個改善在「新增檢視」產生一個View頁面時,支援Model中繼資料(metadata)在表單的data annotation屬性。
新可覆寫方法"Html.LabelFor"和"Html.LabelForModel"
對於 LabelFor 和 LabelForModel 輔助方法增加了新的多載方法,新的多載讓你能指定或覆寫 Label 文字。支援Sessionless Controller
ASP.NET MVC 3中,在Controller類別中,你可以指定是否使用session狀態,更進一步,Session是否能讀寫或者只唯讀。新"AdditionalMetadataAttribute"類別
你能使用 AdditionalMetadata 屬性對 Model 的一個屬性訪問 ModelMetadata.AdditionalValues 字典,例如,如果Model有一個屬性僅支援管理者顯示,你可以設定如下:Public Class ProductViewModel Inherits System.Web.Mvc.Controller <AdditionalMetadata("AdminOnly", true)> Public Property RefundCode() As String End Class}
當ProductViewModel轉譯時,這個中繼資料(metadata)將被任何顯示或編輯樣板使用,這可讓你來解譯中繼資料(metadata)資訊。