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("", 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()方法呈现标签时产生的样式。
field-validation-error – 由Html.ValidationMessage()方法呈现标签时产生的样式。
validation-summary-errors – 由Html.ValidationSumamry()方法呈现标签时产生的样式。
可以继承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中增加
接着在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