http://blog.csdn.net/jadexupeng/archive/2009/11/06/4775000.aspx
MVC框架圖如下:
在你決定使用MVC框架或Web Forms模式開發之前,請認真衡量一下各自的優點。
基於MVC的Web應用程序優點: |
它能很容易的管理複雜的應用程 序,將它分爲model,view和controller。 它不能使用view state和服務器控件,這使得MVC框架開發人員擁有對應用程序完全控制的能力。 它使用前端控制器模式,通過單 一的過程處理Web應用程序的請求,這使你可以使用豐富的URL routing來設計應用程序。更多信息可以在MSDN站點的Front Controller查看。 它對測試驅動開發(TDD)提供更好的支持。 它可以讓Web開發者和頁面設計人員控制自己關心的工作,從頁適合大型團隊的開發。 |
基於Web Forms Web應用程序的優點: |
它可以支持事件模型並保存HTTP的狀態,益於線性業務的Web應用程序開發,基於Web Forms應用程序提供了許許多 多的事件和上百種的服務器控件。 它使用頁面控件器模式,在單個 頁面中實面很多的功能。更多信息請參考MSDN站點上的Page Controller。 它使用view state和基於服務器的表單,使得管理頁面狀態信息更加容易。 它適合小的開發團隊,使用高度 集成的控件來提高Web設計人員和網頁設計人員的效率。 一般來說,它適合不是那麼複雜 的應用程序開發,因爲它的頁面類和控件類是合併在一起的,所以相對於MVC模式來說它需要編寫的代碼更少。 |
Asp.net MVC支持ASP.NET框架的特性:
forms的身份驗證和Windows的身份驗證。
URL驗證。
Membership和roles。
輸出和數據緩存。
session和profile狀態管理。
健康狀態監控。
configuration系統和provider架構。
以下表格是ASP.NET MVC執行週期中所處的階段:
階段 |
介紹 |
收到第一次請求 |
在Global.asax文件中將Route對象依次增加到RouteTable對象。 |
執行路由 |
UrlRoutingModule模塊先 從RouteTable集合中依次匹配Route,如果匹配到後就創建RouteData對象,然後使用它來創 建RequestContext(IHttpContext)對象。 |
創建請求MVC處理模塊 |
MvcRouteHandler對象創建一個MvcHandler的實例類型並傳入RequestContext的實例 |
創建controller |
MvcHandler對象使用RequestContext實例以確定IControllerFactory對象(通常是DefaultControllerFactory類的實例)來創建controller實例。 |
執行controller |
The MvcHandler instance calls the controller's Execute method. MvcHandler實例調用controller的Execute方法。 |
調用action |
大多數控制器繼承自Controller基類,ControllerActionInvoker對象確實與其關聯的Controller類中的action然後調用這個方法。 |
在傳統的ASP.NET Web Forms應用程序或ASP中,使用是是URL與頁面一對一的模式,如果你請求服務器上的SomePage.aspx頁面,它就會去磁盤上讀SomePage.aspx,如果沒有找到這個文件,那麼就返回404-頁面未找到錯誤。
ASP.NET MVC應用程序則與前兩 者相反,鍵入的URL並不與文件對應,在ASP.NET MVC應用程序中一個URL對應的是一個Controller的Action,而不是磁盤上的一個頁面。
在傳統ASP.NET和ASP中瀏覽器請求被映射到頁面文件,而ASP.NET MVC應用程序相反, 瀏覽器將請求映射到controller action,在ASP.NET Web Forms是以內容爲中心,但在ASP.NET MVC中是以邏輯爲中心。
當你創建一個新的ASP.NET MVC應用程序的時候,應用程序已經配置好了ASP.NET Routing,在應用程序中有兩個地方涉及到ASP.NET Routing。
第一,配置文件(web.config)中關於ASP.NET Routing中的部分,在這裏有四個配置節點與之有關,system.web.httpModules節、system.web.httpHandlers節,system.webserver.modeuls節和system.web.server.handlers節,在這裏要小心,如果不小心刪掉它們,那麼將導致ASP.NET Routing無法正常工作。
第二,這一點也很重要,route table在一個特殊的文件Global.asax中,此方件包含了ASP.NET應用程序生命週期中的很多事件,Route table就是在Application_Start(應用程序啓動的事件)中被創建的。
ASP.NET Routing Table在特殊的時候,可以對它進行一些定製。比如當一個用戶輸入/Archive/12-25-2009可以返回2009-12-25日的博客,這時需要定製一個routes.MapRoute( "Blog", "Archive/{entryDate}", new { controller = "Archive", action = "Entry" } );
還可以使用Routing約束規則來要求對URL進行完整的嚴格匹配,當不能完成約束的匹配時就不執行這個URL Routing例如:routes.MapRoute("Product", "Product/{productId}",
new {controller="Product", action="Details"},
new {productId = @"\d+" } );
還可以自定義約束類來約束URL Routing,在類中進行更爲特殊的約束判斷,例如:
Golbal.asax文件
routes.MapRoute( "Admin", "Admin/{action}",
new {controller="Admin"},
new {isLocal=new LocalhostConstraint()} );
LocalhostConstraint.cs文件
public class LocalhostConstraint : IRouteConstraint
{
public bool Match ( HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection )
{
return httpContext.Request.IsLocal;
}
}
正確創建Controller需要遵守以下約定
必須要創建在Controlller文件夾中
必須要直接或間接繼承自System.Web.Mvc.Controller基類
類必須要以Controller結尾,如:HomeController
使用Repository Pattern訪問數據層可以讓應用程序變得易於測試,不要將數據庫的訪問代碼直接放入Controller。使Controller與數據訪問依賴接口。
正確定義action需要遵守以下約定:
方法必須是public的
不能是靜態方法
不能是擴展方法
不能是構造器或屬性
不能是範型的
不能與在Controller基類中方法重複
方法的參數不能是ref和out。
如果需要創建一個 不是controller action的public方法,需要在方法前加入[NonAction]屬性。
Controller類可以進行繼承,來 提高複用性。
每個Action都返回繼承自ActionResult的類型,如果返回的是非ActionResult類型那麼ASP.NET MVC框架會將其包裝成ContectResult返回。
Action Results的種類
ViewResult – 表示HTML標籤類型的結果.
EmptyResult – 表示沒有返 回結果.
RedirectResult – 表示 重定向到一個新的URL.
JsonResult – 表示在AJAX應用程序中的一個JavaScript對象格式(JSON)結果。
JavaScriptResult – 表 示JavaScript結果.
ContentResult – 表示純 文本結果.
FileContentResult – 表 示二進制,可下載的文件結果.
FilePathResult – 表示 一個路徑,可下載的文件結果.
FileStreamResult – 表 示一個流,可下載的文件結果.
ASP.NET MVC框架定義了一些方法輔助返回各種類型的ActionResult:
View – 返回一個ViewResult實例的action result.
Redirect –返回一個RedirectResult實例的action result.
RedirectToAction ––返 回一個RedirectToRouteResult實例的action result.
RedirectToRoute –返回 一個RedirectToRouteResult實例的action result.
Json –返回一個JsonResult實例的action result.
JavaScriptResult –返 回一個JavaScriptResult實例的action result.
Content –返回一個ContentResult實例的action result.
File –返回FileContentResult、FilePathResult或 FileStreamResult實例,這依賴於傳遞到方法中去的參數.
ASP.NET MVC 框架包含的HTML Heplers:
Html.ActionLink()
Html.BeginForm()
Html.DropDownList()
Html.EendForm()
Html.Hidden()
Html.ListBox()
Html.Password()
Html.RadioButton()
Html.TextArea()
Html.TextBox()
ViewData是一個名/值對的集合,它是將數據從Controller傳遞到View的重要橋樑,它的優點是方便、容易使用。缺點是弱類型,使用時容易出錯。
ViewData可以在MasterPage中使用。
在View中顯示數據時最好調用Html.Encode()來防止Javascript注入***。
同樣可以防止JavaScript***的辦法還可以在服務器端保存數據時調用Server.HtmlEncode()方法。
自定義Html Helper的方法:
public static class LabelExtensions {
public static string Label(this HtmlHelper helper, string target, string text)
{
return String.Format("<label for='{0}'>{1}</label>", target, text);
}
}
建議使用強類型的View,爲每個View定義一個強類型的View Model。
保證View符合 DRY原則,可以經常使用Partial View來提高複用,例如將一個表格的行提取出來放入一個Partial View中<% Html.RenderPartial(); %>
可以使用Microsoft Data Entity Framework或Linq To SQL在Model中創建數據訪問層。
在View中使用驗證時需要實現三個CSS樣式:
input-validation-error – 由Html.TextBox()方法呈現<input>標籤時產生的樣式。
field-validation-error – 由Html.ValidationMessage()方法呈現<span>標籤時產生的樣式。
validation-summary-errors – 由Html.ValidationSumamry()方法呈現<ul>標籤時產生的樣式。
可以繼承IDataError接口來結合Microsoft Data Entity Framework的模型進行自定義的驗證。
最好是將驗證代碼放入到Service Layer中,讓Controller調用Service,然後Service再調用Repository,另外需要注意的是要讓Controller與Service不要耦合,不要依賴ModelState,而是依賴一個IValidationDictionary接口。
Repository IRepository Service IService IValidationDictionary ModelStateWrapper Controlller 測試Mock ModelStateMock MockRepository MockService
還有一個組件可以幫助我們更快 的進行驗證要求。Data Annotations Model Binder 可 以去這裏下載here。它提供了幾種驗證方 式:
Range – 能夠驗證你的屬性值是否 在允許的範圍。
ReqularExpression – 能 夠驗證你的屬性值是否匹配正則表達式。
Required – 能夠驗證此屬性是 否是必須的,不能爲空或NULL
StringLength – 能夠驗證 屬性的長度是否符合要求
Validation – 全部驗證屬性 的基類。
它的使用方法很簡單,將System.ComponentModel.DataAnnotations.dll和Microsoft.Web.Mvc.DataAnnotations.dll引入進工程。
接着在Global.asax中註冊
protected void Application_Start(){
RegisterRoutes(RouteTable.Routes);
ModelBinders.Binders.DefaultBinder = new Microsoft.Web.Mvc.DataAnnotations.DataAnnotationsModelBinder();
}
最後在自己的數據映射類中加入 需要驗證方式。
[Required]
[StringLength(5)]
public object Director { get; set; }
全部的Filter繼承自System.Web.Mvc.FilterAttribute
ASP.NET MVC 框架提供了三類 action filters:
OutputCache – 這個action filter可以在一定的時間中緩存controller action的結果.
HandleError – 這個 action filter處理controller action執行中產生的錯誤。
Authorize – 這個 action filter進行訪問限制,控制用戶和角色的訪問權限。
ASP.NET MVC 框架提供四種不同類型的filters:
Authorization filters – 繼承了 IAuthorizationFilter 屬性。
Action filters – 繼承 了 IActionFilter 屬性。
Result filters – 繼承 了IResultFilter 屬性。
Exception filters – 繼 承了 IExceptionFilter 屬性。
要使用緩存不要在Page頁面中加入<% OutpubCache %>,而要在Controller或是在Controller action中加入[OutputCache],例如:
[OutputCache(Duration=10, VaryByParam="none")]
public ActionResult Index(){return View();}
Location可以將以下幾種緩存放在:
· Any --- 默認,根據系統運行情況自動緩存的位置。
· Client --- 緩存在客戶端。
· Downstream --- 下載流緩存。
· Server --- 緩存在服務器上。
· None --- 不緩存在任何地方。
· ServerAndClient --- 服務器和客戶端全部都緩存。
可以使用Cache Profile模式進行緩存,具體方法是在web.config中增加
<system.web>
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name="Cache1Hour" duration="3600" varyByParam="none"/>
</outputCacheProfiles>
</outputCacheSettings>
</caching>
</system.web>
接着在Controller中增加
public class ProfileController : Controller
{
[OutputCache(CacheProfile="Cache1Hour")]
public string Index()
{
return DateTime.Now.ToString("T");
}
}
當一個頁面有些地方不需要緩存 而其它地方需要緩存時(比如在一個新聞頁中的廣告位),可以在View中使用<% Response.WriteSubstitution(News.RenderNews); %>該方法接收一個回調方法。
Authentication Filter使用的是Forms的驗證體系,使用方法和以前的使用方法類似,只是以前在類或方法的前加[Authorize]現在換成了在Controller action中加入此屬性。此功能依然需要與AspNetDB數據庫聯合使用。
對每一段代碼都進行嚴格的單元 測試將確保你的代碼安全可靠便於重構,例如在測試一個Controller action是否執行正確並返回所希望的View時,可以使用下面的測試代碼:
[TestMethod]
public void TestDetailsViewData() {
var controller = new ProductController();
var result = controller.Details(2) as ViewResult;
var product = (Product) result.ViewData.Model;
Assert.AreEqual("Laptop", product.Name);
}
------------------------------- 官方指南學習總結結束 ----------------------------------
許鵬
2009-11-6