ASP.NET Routing模块的责任是将传入的浏览器请求映射为特有的MVC controller actions。
http://www.cnblogs.com/jasenkin/archive/2010/08/16/1801082.html
使用默认的Route Table
当你创建一个新的ASP.NET MVC应用程序,这个应用程序已经被配置用来使用ASP.NET Routing。 ASP.NET Routing 在2个地方设置。第一个,ASP.NET Routing 在你的应用程序中的Web配置文件(Web.config文件)是有效的。在配置文件中有4个与routing相关的代码片段:system.web.httpModules代码段,system.web.httpHandlers 代码段,system.webserver.modules代码段以及 system.webserver.handlers代码段。千万注意不要删除这些代码段,如果没有这些代码段,routing将不再运行。第二个,更重要的,route table在应用程序的Global.asax文件中创建。这个Global.asax文件是一个特殊的文件,它包含ASP.NET 应用程序生命周期events的event handlers。这个route table在应用程序的起始event中创将。
在Listing 1中包含ASP.NET MVC应用程序的默认Global.asax文件.
Listing 1 - Global.asax.cs
2 {
3 public static void RegisterRoutes(RouteCollection routes)
4 {
5 routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
6 routes.MapRoute(
7 "Default", // 路由名称
8 "{controller}/{action}/{id}", // 带有参数的 URL
9 new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 参数默认值
10 );
11
12 }
13
14 protected void Application_Start()
15 {
16 AreaRegistration.RegisterAllAreas();
17
18 RegisterRoutes(RouteTable.Routes);
19 }
20 }
当一个MVC应用程序第一个启动,Application_Start() 方法被调用,这个方法反过来调用RegisterRoutes() 方法。
这个默认的route table包含一个单一的route。这个默认的route将url的第一个段映射为一个controller名称,url的第二个段映射为一个controller action,第三个段映射为命名为id的参数。
假如,你在网页浏览器的地址栏中键入下面的url:/Home/Index/3,这个默认的route将这个url映射为下面的参数:
controller = Home controller名称
action = Index controller action
id = 3 id的参数
当你请求/Home/Index/3这样的url,下面的代码将执行。HomeController.Index(3)
这个默认的route包含3个默认的参数。如果你没有提供一个 controller,那么 controller默认为Home。同样,action默认为Index,id参数默认为空字符串。
让我们来看一些关于默认的route怎么映射urls为controller actions的例子。假如你在你的浏览器地址栏中输入如下的url:/Home, 由于这些默认的route参数有一些相关的默认值,键入这样的URL,将导致HomeController类的Index()方法(如Listing 2)被调用。
2 {
3 [HandleError]
4 public class HomeController : Controller
5 {
6 public ActionResult Index(string id)
7 {
8 ViewData["Message"] = "欢迎使用 ASP.NET MVC!";
9
10 return View();
11 }
12
13 public ActionResult About()
14 {
15 return View();
16 }
17 }
18 }
19
20
在Listing 2中,这个HomeController 类包含一个名为Index()的方法。这个URL /Home导致Index()方法被调用,一个空的字符串将作为id参数的值。由于mvc框架调用controller actions的这种方式,这个URL /Home同样匹配HomeController类中的Index()方法(如Listing 3)。
Listing 3 - HomeController.cs (Index action with no parameter)
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
在Listing 3中,这个Index()方法不接收任何参数。这个URL /Home将导致Index()方法被调用。URL /Home/Index/3同样调用这个方法(ID被忽略)。
Listing 4 - HomeController.cs (Index action with nullable parameter)
[HandleError]
public class HomeController : Controller
{
public ActionResult Index(int? id)
{
return View();
}
}
在Listing 4中, Index() 方法有一个整数参数. 由于这个参数是可空参数 , Index() 将被调用而不引起错误.
最后, 使用 URL /Home 来调用如Listing 5中的Index() 方法 将导致异常,因为这个ID参数不是一个可空的参数。如果你试图去调用这个Index()方法,你将获得如下图所示的错误。
Listing 5 - HomeController.cs (Index action with Id parameter)
[HandleError]
public class HomeController : Controller
{
public ActionResult Index(int id)
{
return View();
}
}
另一方面,使用如Listing 5中的Index controller action,URL /Home/Index/3运行正常。Index controller action in Listing 5. /Home/Index/3请求将导致Index()方法被调用,ID参数拥有一个3的值。
总结
这是一个关于ASP.NET Routing的简要介绍. 应该了解了这个默认的route如何将URLs映射为controller actions。
创建自定义的Routes (C#)
这个教程,你将学会怎样添加一个自定义的route到一个asp.net mvc应用程序。你将学会在Global.asax文件中,怎样使用一个自定义的route来修改这个默认的route table。
对于许多简单的ASP.NET MVC 应用程序,这个默认的route table将运行得很好。然而,你可能发现,你可能特定的routing 需求。那样的话,你可能需要创建一个自定义的route。
设想一下,例如,你正在建立一个博客应用程序,你可能想要去处理像/Archive/12-25-2009的输入请求。
当一个用户键入这个请求,你想要返回与日期为12/25/2009相符的博客实体。为了处理这种类型的请求,你需要去创建一个自定义的route。
在 Listing 1中,这个Global.asax文件中包含一个新的名为Blog的自定义route,它处理类似于/Archive/entry date的请求。
Listing 1 - Global.asax (with custom route)
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5 using System.Web.Mvc;
6 using System.Web.Routing;
7
8 namespace MvcRoutingApp
9 {
10 // 注意: 有关启用 IIS6 或 IIS7 经典模式的说明,
11 // 请访问 http://go.microsoft.com/?LinkId=9394801
12
13 public class MvcApplication : System.Web.HttpApplication
14 {
15 public static void RegisterRoutes(RouteCollection routes)
16 {
17 routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
18 routes.MapRoute(
19 "Blog", // 路由名称
20 "Archive/{entryDate}/{id}", // 带有参数的 URL
21 new { controller = "Archive", action = "Entry", id = UrlParameter.Optional } // 参数默认值
22 );
23 routes.MapRoute(
24 "Default", // 路由名称
25 "{controller}/{action}/{id}", // 带有参数的 URL
26 new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 参数默认值
27 );
28
29 }
30
31 protected void Application_Start()
32 {
33 AreaRegistration.RegisterAllAreas();
34
35 RegisterRoutes(RouteTable.Routes);
36 }
37 }
38 }
你添加到route table的routes的顺序是很重要的。我们新自定义的blog route在现存的默认route之前添加。如果你颠倒了顺序,那么这个默认的route总是先调用而不是这个自定义的route。
这个自定义的blog toute匹配任何以 /Archive/ 开头的请求。所以,它匹配所有下列URLs:
/Archive/12-25-2009
/Archive/10-6-2004
/Archive/apple
这个自定义的route将输入的请求映射至名为Archive的controller,并且调用 Entry() action。当 Entry() action被调用的时候,这个输入的日期被当作名为entryDate的参数。
Listing 2 - ArchiveController.cs
public class ArchiveController : Controller
{
public string Entry(DateTime entryDate)
{
return "You requested the date:" + entryDate.ToString();
}
}
注意,在Listing 2中这个Entry()方法接收一个类型为DateTime的参数。MVC框架是足够智能的,它自动将URL中输入的date转换为一个DateTime值。如果URL中输入的date不能转换为DateTime,错误将被引发。
总结
这个教程演示怎样来创建一个自定义的route。你学会了怎样在Global.asax 文件中添加一个自定义的route到route table。我们讨论了怎样为blog实体将请求映射为名为ArchiveController的controller,名为Entry()的controller action。
理解MVC应用程序执行过程
基于ASP.NET MVC Web应用程序的请求首先通过一个UrlRoutingModule的对象(HTTP模块)。这个模块匹配请求,并且执行路由选择。这个UrlRoutingModule对象选择第一个匹配当前请求的路由对象。如果没有路径匹配,这个UrlRoutingModule什么也不做,让这个请求返回给常规的ASP.NET或者IIS来请求处理。
从这个被选中的Route对象,UrlRoutingModule对象获得IRouteHandler对象(IRouteHandler对象与Route对象是相互关联的)。一般来说,在一个MVC应用程序中,它将是MvcRouteHandler实例。这个IRouteHandler实例创建一个IHttpHandler对象,并且将它传递给IHttpContext对象。默认情况下,MVC IHttpHandler实例就是MvcHandler对象。然后,这个MvcHandler对象选择controller,controller将最终提交这个请求。
这个module 和 handler是ASP.NET MVC框架的入口点。它们执行下列行为:
选择合适的controller。
获得一个具体controller实例。
调用controller的执行方法。
下表列出了一个MVC Web项目的执行的各阶段。
阶段 | 详细 |
接收应用程序的第一次请求 | 在Global.asax文件中, Route对象 被添加到RouteTable对象. |
执行路由选择 | UrlRoutingModule 模块使用第一个在RouteTable 集合中匹配的Route 对象来创建RouteData对象, 然后它将使用这个RouteData对象来创建RequestContext (IHttpContext)对象. |
创建MVC request handler | MvcRouteHandler 创建MvcHandler类的一个实例,并且将它传递给RequestContext实例. |
创建controller | MvcHandler对象使用RequestContext实例来确认IControllerFactory 对象(DefaultControllerFactory类的一个实例) ,以用来创建conteoller实例。 |
执行controller | MvcHandler 实例调用controller的执行method. |
调用action | 大部分controllers 继承自Controller基础类. 与controller相关联的ControllerActionInvoker 对象决定这个controller类的哪个方法将被调用 , 然后再调用那个方法. |
执行result | 一个典型的action 方法可能接收用户输入,准备合适的响应数据, 然后通过返回一个result的类型来执行这个result. 这个内置的能够执行的result 类型 包含以下类型: ViewResult (它呈现一个视图,并且是最常用的result类型), RedirectToRouteResult, RedirectResult, ContentResult, JsonResult以及EmptyResult. |
ASP.NET MVC 概述
了解关于 ASP.NET MVC 应用程序与ASP.NET Web Forms 应用程序两者之间的不同点. 了解怎样去决定什么时候创建一个 ASP.NET MVC 应用程序.
ASP.NET MVC 概述(C#)
模型-视图-控制 (MVC) 结构模式将一个应用程序分隔成三个主要组成部分:模型层、视图层、控制器。ASP.NET MVC框架提供了另一种可以替代ASP.NET Web Forms模式的选择来创造基于MVC的 web应用程序。ASP.NET MVC 框架是一个轻量级的框架,它与现有的ASP.NET特征相集成,比如母板页与基于身份的验证。MVC框架下定义在System.Web.Mvc命名空间中。
MVC是许多开发者都很熟悉的标准设计模式。很多类型的Web应用程序将会受益于MVC框架。一部分将依旧会继续使用传统的基于Web Forms和回传的ASP.NET应用程序模式。其他类型的 Web应用程序将这两种方法相结合使用:两者互不排斥。
MVC框架包含以下组成部分:
•模型层。模型对象是应用程序的一部分,它实现了应用程序的数据定义的逻辑。通常,模型对象检索和储了在数据库中的模型状态。例如,一个Products对象可以在数据库检索信息,操作它,然后将修改的信息更新回SQL服务器中的Products表。
在小应用程序中,该模型常常是一个概念性的分离而不是物理上的。例如,如果应用程序仅仅读取数据集和将它发送到视图上,应用程序将不存存在一个物理模型层及相关的类。在这种情况下,数据集将具有一个模型对象的角色。
•视图层。视图层是显示应用程序的用户界面(UI)的部分。通常,用户界面UI是由模型数据所创建的。
•控制层。控制层是处理用户交互,对模型层起作用,并最终选择一个视图view来呈现那个显示的用户界面的部分。在一个MVC应用程序中,视图层view只显示信息,控制层controller处理并响应用户的输入和交互。例如,控制层处理查询字符串的值,并将这些值传递给模型层model,该模型层就会反过来使用这些值来查询数据库。
MVC模式帮助你创建应用程序,它将应用程序的不同方面的(输入逻辑、业务逻辑,和UI逻辑)进行分离,同时在这些元素之间提供一个松耦合关系。这种模式指定了每一种逻辑在应用程序中所处的位置。UI逻辑属于视图层。输入逻辑属于控制层。业务逻辑属于模型层。当你创建一个应用程序时,这种分离能帮助你处理复杂事务,因为它可以让您每一次专注于实施的一个方面。例如,你可以专注于视图层,而不依赖任何业务逻辑。
除了管理复杂的事务,MVC模式比基于Web Forms的ASP.NET Web应用程序更加容易进行测试。例如,在一个基于Web Forms的ASP.NET Web应用程序,一个单一的类被用于显示输出和响应用户的输入。因为测试单个页面,你必须实例化这个页面page类,它所有的子控件以及应用程序中额外的依赖类,所以针对于基于Web Forms的 ASP.NET应用程序写的自动测试将可能很复杂。因为有那么多类被实例化用来运行这个页面,它可能很难写出针对于应用程序的单个部分的测试代码。因此,基于Web Forms的ASP.NET Web应用程序的测试比MVC应用程序更难实现。而且,基于Web Forms的ASP.NET Web应用程序需要一个Web服务器。MVC框架将这些组成部分进行解耦,大量的使用接口,使它能够独立的测试单独的部分。
同样,MVC应用程序中的介于三个主要组成部分的松耦合也促进了平行开发。例如,一个开发者可以开发视图层,另一个开发者可以开发控制逻辑层,第三个开发者可以专注于模型层中的商业逻辑。
决定什么时候去创造一个MVC应用程序
你必须仔细考虑是否要通过采用ASP.NET MVC框架和ASP.NET Web Forms模型中任何一种来实施一个Web应用程序。MVC框架取代Web Forms模型;你能够为Web应用程序采用任何一种框架。
在你为一个具体的Web站点决定采用MVC框架还是Web Forms模型之前,权衡一下每一种方法的优势。
基于MVC的Web应用程序的优势
这个ASP.NET MVC框架提供了以下优点:
它通过将应用程序分解为模型层,视图层和控制层来使我们更容易管理复杂的事务。
它不使用视图状态或基于服务器的表单。这使得MVC框架非常适合于那些想完全控制应用程序行为的开发者。
它使用一个 Front Controller模式,它通过一个单一的控制器来处理Web应用程序请求。这使你能设计一个支持丰富的路由基础设施的应用程序。更多信息,在MSDN网站查询Front Controller。
它提供更好的驱动测试开发的支持(TDD)。
它适用于需要高度控制程序行为的开发者和网站设计者支持的应用程序的大型团队。
基于Web Forms的Web应用程序的优点
基于Web Forms的框架提供以下优点:
它支持一个能够在HTTP之上保持状态的事件模型,从而有利于line-of-business网页应用软件的开发。基于Web Forms的Web应用程序提供了被数以百计的服务器控件支持的许多事件。
它使用一个能够增加函数到单个页面的页面控制模式,。更多信息,见MSDN网站中的Page Controller。
它使用视图状态或基于服务器的表单,它可以使管理状态信息更加容易。
它适用于那些网站开发者和设计师想利用大量组件来快速应用开发的小团队。
总的来说,应用软件的开发不是那么复杂,因为组件(页类、控件等)是紧密结合在一起,通常比MVC模型需要更少的代码。
ASP.NET MVC 框架的特点
ASP.NET MVC 框架提供了以下特点:
分离的应用程序任务(输入逻辑、业务逻辑,和UI逻辑)、可测性、默认的驱动测试开发(TDD)。所有在MVC框架中的核心是interface-based和可以利用模拟对象进行测试,模拟对象能够模拟实际应用中对象的真实行为。你不一定需要在ASP.NET进程中运行控制层就能够对应用程序进行单元测试,它使得单元测试更快速和灵活。你可以使用任何兼容.net框架的单元测试框架。
一个可扩展和可插接的框架。这个ASP.NET MVC框架的组件被设计过,这样它们就能够方便地更换或自定义。你可以插入你自己的视图引擎,URL路由策略,action-method参数的序列化以及其他组件。这个 ASP.NET MVC 框架也支持使用依赖性注射(DI)和控制反转(IOC)容器模型。DI允许您注入对象到一个类中,而不是依赖这个类来创建对象本身。IOC规定,如果一个对象需要另一个对象,第一个对象应该得到来自外部源(如一个配置文件)的第二个对象。这使得测试更容易。
一个强大的URL-mapping组件,它让你建立拥有可理解并且可搜索的URL的应用程序。URL并不需要包括文件扩展名,是设计用来支持URL命名模式, 这种模式对于搜索引擎优化(SEO)和表述性状态转移(REST)寻址能够很好的运行。
支持现有的ASP.NET 功能。ASP.NET MVC让你使用功能,如表格认证和Windows认证、URL的授权,成员和角色,输出和数据缓存,会话和状态管理等。