标签:索引 增加 new back 同名 route color 利用 全局
System.Web.Routing下的类型
此命名空间下定义了与路由机制有关的类型#55a4dd
RouteTable(路由表)
表示全局路由的类
RouteCollection(路由集合)
表示路由列表的类,此类通过RouteTable.Routes获得。
Ignore ( )
//如果RouteExistingFiles是默认的false,则任何文件都可以通过请求该文件的物理地址从而得到这个文件
//如果RouteExistingFiles被手动设为true,那么任何文件都不再可以通过请求该文件的物理地址从而得到这个文件
//所以在RouteExistingFiles为true的情况下,如果我们想增加一些例外,比如你不希望css或js文件的请求需要通过路由地址访问,
//你希望可以通过在浏览器直接输入文件的物理地址就能访问该类型的文件,那么此时才有使用Ignore()方法的必要。
//注意,所有不需要通过路由地址才能访问的文件必须使用Ignore()方法定义且必须放在路由注册的前面,否则无效
//示例:
routes.RouteExistingFiles = true; //请求的任何文件必须使用路由地址访问
routes.Ignore ( "{resource}.css/{*pathInfo}" ); //指示css文件不必通过路由地址访问
IgnoreRoute ( )
//与Ignore()方法等同
MapPageRoute ( )
//RouteCollectionExtentions为RouteCollection定义的扩展方法,此方法需要引用System.Web.Mvc程序集。
//注册一个路由,将Url地址映射为路由模板,比如将一个aspx页面地址映射为路由模板,这样你可以通过路由模板对default.aspx进行访问。
//示例:
RouteTable.Routes.MapPageRoute ( "" , "employees/{name}/{id}/{*other}" , "~/Default.aspx" , true , defaults );
//有了以上的针对具体某一个页面(default.aspx)的路由映射,现在可以直接在浏览器输入http://localhost/employees/sam/1001访问到default.aspx
MapRoute ( )
//RouteCollectionExtentions为RouteCollection定义的扩展方法,此方法需要引用System.Web.Mvc程序集。
//此方法专门用于在ASP.NET MVC框架下注册一个路由,区别于MapPageRoute ( )方法
//此方法并非将某一页面的物理地址映射为一个路由地址,它是定义了一个与任何页面进行匹配的路由模板,且模板必须具有Contrller和Action变量。
//以下使用MapRoute ( )方法添加了一个路由
//注意,MapRoute()方法的Defaults、Constraint参数不再是RouteValueDictionary,而是object,这是为了编程的便利性,最终它们还是会被路由机制自动转化为RouteValueDictionary
//示例:
routes.MapRoute (
name: "Default" ,
url: "{controller}/{action}/{id}" ,
defaults: new { controller = "Home" , action = "Index" , id = UrlParameter.Optional }
);
//当请求的路由地址被服务端接收后,服务端将在全局路由范围内查找匹配的路由模板
//假设在另一个项目或不同命名空间下存在同名的Controller,那么路由机制如何确定应将请求路由到哪个Controller中呢?
//通过指定namespaces可以使路由查找机制优先考虑使用namespaces所指定的Controller
routes.MapRoute ( name: "Default" , url: "{controller}/{action}/{id}" ,
namespaces: new string [ ] { "My.Controllers" } , //优先使用My.Controllers命名空间下的Controller
defaults: new { controller = "Home" , action = "Index" , id = UrlParameter.Optional });
GetVirtualPath ( RequestContext requestContext,RouteValueDictionary values )
//遍历全局路由列表,查找与values存储的路由模板变量值完全匹配的路由模板
//如果匹配成功则返回一个VirtualPathData对象,否则返回null。通过VirtualPathData.VirtualPath可以获取到匹配成功后的路由地址
//示例:在aspx页面中:
string employeeID = RouteData.Values [ "id" ] as string;
System.Web.Routing.RequestContext context = new System.Web.Routing.RequestContext ( );
context.HttpContext = new HttpContextWrapper ( HttpContext.Current );
context.RouteData = RouteData;
string s = RouteData.Route.GetVirtualPath ( context , RouteData.Values ).VirtualPath; //return like:/employees/sam/1001
GetVirtualPath ( RequestContext requestContext,RouteValueDictionary values , string RouteName )
//根据参数指定的路由名称找到该路由,将values存储的路由模板变量值与该路由的路由模板进行匹配
//如果匹配成功则返回一个VirtualPathData对象,否则返回null。通过VirtualPathData.VirtualPath可以获取到匹配成功后的路由地址
GetRouteData(RequestContext httpContext);
//如果当前请求的Url成功匹配了路由模板则返回与当前请求相关的、存储了路由信息的RouteData实例
//示例:手动创建一个HttpContextBase,通过代码来模拟一次客户端的请求以便获得RouteData
HttpRequest request = new HttpRequest ( "/Home/Index" , "http://localhost:53326/Home/Index" , null );
HttpResponse response = new HttpResponse ( new System.IO.StringWriter ( ) );
HttpContext context = new HttpContext ( request , response );
HttpContextBase contextWraper = new HttpContextWrapper ( context );
routeData =RouteTable.Routes.GetRouteData ( contextWraper );
RouteExistingFiles
//如果将此属性设为true,则所有Url请求都将强制路由匹配。默认false,也即在默认情况下,Url地址的模式可以是某个文件地址的模式也可以是路由模板的模式
//比如假设现在请求的是aspx页面,在浏览器直接输入此页面的地址:http://localhost/default.aspx,因为默认情况下RouteExistingFiles是false,所以对这个页面的直接请求并不会进入路由匹配。
Route(路由)
表示单个路由的类
Defaults;
//一个RouteValueDictionary泛型字典集合,用于为路由的路由模板设置变量的默认值
//示例:
Route route = new Route ( "employees/{name}/{id}/{*other}" , new PageRouteHandler ( "~/default.aspx" );
route.Defaults= new RouteValueDictionary
{
{ "name","sam" },
{ "id","1001" }
};
Constraints;
//一个RouteValueDictionary泛型字典集合,用于为路由设置约束,如果当前路由匹配成功,就要进入约束,约束用于验证某些自定义的逻辑,没通过验证则路由会失败
route.Constraints = new RouteValueDictionary
{
{ "controller" , @"\d{4}" }, //为路由模板的controller变量设置了正则式约束
{ "httpMethod", new HttpMethodConstraint ( "GET" ) } //设置了请求约束,请求必须是Get请求
};
DataTokens;
//一个RouteValueDictionary泛型字典集合,这是一些不经过路由匹配的查询字符串变量集合
GetRouteData ( )
//将请求的Url和路由进行匹配,如果匹配失败,返回null,否则返回一个RouteData实例
GetVirtualPath ( RequestContext requestContext,RouteValueDictionary values )
//将values存储的路由模板变量值与当前路由的路由模板进行匹配,如果匹配成功则返回一个VirtualPathData对象,否则返回null。通过VirtualPathData.VirtualPath可以获取到匹配成功后的路由地址
GetRequiredString ( string key )
//在RouteData的Values中查找路由变量所对应的值,key是路由变量的名称。注意,如果key不存在则会抛出异常。
Url
//获取路由对象的模板,即类似这样的路由模板:employees/{name}/{id}
RouteData(路由信息)
表示存储路由有关信息的类,在ASP.NET WEB FORMS的页面中,如果某个请求被映射为路由并成功匹配了路由,此时Route对象会调用它的GetRouteData()方法,该方法会返回一个RouteData对象,它将这个对象赋值给了Page类的RouteData属性,所以在页面中可以直接访问RouteData来获取路由的相关信息。
Route
//获取路由对象
Values
//一个RouteValueDictionary的泛型字典集合,存储了路由变量。Key是路由变量的名称,Value是变量的值。
DataTokens
//一个RouteValueDictionary的泛型字典集合,存储了直接附加到路由上的自定义变量(不会参与路由匹配的查询字符)。Key是变量的名称,Value是变量的值。
RouteHandler
//一个实现了IRouteHandler接口的对象,该对象因为实现了接口的GetHttpHandler()方法,所以它可以用于处理Http请求。
VirtualPathData(路由信息)
表示存储路由有关信息的类
Route
//获取路由对象
VirtualPath
//获取根据匹配好的路由所生成的Url,比如将employee/3001生成为employee/id这样的格式
DataTokens
//一个RouteValueDictionary的泛型字典集合,存储了直接附加到路由上的自定义变量(不会参与路由匹配的查询字符)。Key是变量的名称,Value是变量的值
RequestContext(特殊的Http上下文)
此类封装了当前的路由信息和Http请求的上下文
HttpContext
//获取当前Http请求的上下文
RouteData
//当前的路由信息
ASP.NET中的路由
ASP.NET本身就具有路由的机制,只不过没有得到使用,当发起一个请求时是直接请求的该文件的物理地址。其实在System.Web.Routing命名空间中就有一些关于路由的类型,我们也可以使用这些类型将Url请求映射为路由地址,一个传统的Url请求可能是这样的:
http://www.cnblogs.com/employees/GetList.aspx
而路由地址是这样的:
http://www.cnblogs.com/em/All
传统的Url请求中的employees是文件夹,GetList则是具体的物理文件,而路由请求中的em不是文件夹,All也不是物理文件。路由地址的好处显而易见,它隐藏了真实文件的地址,而且便于搜索引擎优化。
ASP.NET MVC中的路由
ASP.NET MVC也使用System.Web.Routing命名空间中路由机制,但它有别于ASP.NET WEB Forms中的路由,在System.Web.Mvc程序集中有一个RouteCollectionExtentions类,此类为System.Web.Routing.RouteCollection类定义了一系列的扩展方法专门用于ASP.NET MVC框架下的路由机制。扩展出了MapRoute、IgnoreRoute方法,使用MapRoute注册的路由必须具有Contrller和Action,以便路由机制在成功匹配客户端请求的路由地址后可以将处理请求的程序(IHttpHandler)对接到对应的Controller和Action上。
路由匹配
路由匹配的意思是:当用户在浏览器地址栏输入一个Url后,这个Url请求会发送到服务端,由服务端的处理程序解析,所有的路由都注册在RouteTable的路由列表中,所以路由处理程序会自动在RouteTable的路由列表中搜索与Url匹配的路由,如果这个Url能匹配某个路由模板,就会自动进入该路由所对应的Controller和Acion以便处理Http请求。路由模板定义在Route的Url属性中,也即如果我们要注册一个路由,就要为路由定义一个路由模板,这个模板被放在Route的Url属性中。
定义路由模板
Route具有一个Url属性,该属性用于为路由设置一个路由模板
Url: "employee / { controller } / { action } / { id }"
//这是一个路由模板(也称Url模板、Url模式)
//每个被 / 分隔的段称为segment
//每个segment可以有两种类型的参数
//要么是segment常量,要么是segment变量
//segment常量就是一个文本值
//segment变量则使用:{ 变量名 },以此作为占位符
路由匹配规则
请求的Url的段数与路由模板的段数必须相等且常量值相等。
所以下面的Url可以匹配上面定义的路由模板:
employee匹配了路由模板的常量值
details匹配了路由模板的Controller变量,即Controller变量的值是details
employeeDetails匹配了路由模板的Action变量,即Action变量的值是employeeDetails
1001匹配了路由模板的Id变量,即id变量的值是1001
注:常量不会当做控制器或Action,这两个段必须以变量的形式定义
路由模板的变量默认值
Route具有一个Defaults的属性,设置Defaults是预防当请求的Url没有提供变量值时将使用默认值填充路由模板,如果请求的Url提供了变量值则不会应用Defaults。
defaults: new { controller = "Home" , action = "Index" }
//如果请求的Url没有提供controller变量的值和action变量的值则使用默认值进行填充
因为请求的Url没有提供变量值,所以使用了默认值对模板进行填充,模板最终生成的地址是:employees/Home/Index
默认值UrlParameter.Optional
如果不确定要为变量设置怎样的默认值,那就将变量的默认值设为UrlParameter.Optional即可。
url: "{controller}/{action}/{id}" ,
defaults: new { controller = "Home" , action = "Index" , id = UrlParameter.Optional }
无需匹配的变量值
使用*号定义的变量不会参与匹配,如:
url: "Files / { controller } / { action } / { name } / { *otherSegments }"
//请求的Url如果没有最后一个段,也能匹配
路由约束
Route具有一个constraints属性,该属性用于为路由设置约束。有两种方式可以添加路由约束,一是使用正则式,二是自定义一个约束类
正则式约束
//约束了controller变量的值必须是4个数字 同时该请求必须是GET的
constraints: new { controller = @"\d{4}", httpMethod = new HttpMethodConstraint ("GET") },
自定义约束
自定义约束类必须实现IRouteConstraint接口,实现的Match()方法返回true表示通过验证。以下创建了一个LocalhostConstraint的类,它实现的Match()方法用于检测请求是否来自本地计算机,如果不是则不匹配路由。
public class LocalhostConstraint : IRouteConstraint
{
public bool Match ( HttpContextBase httpContext , Route route , string parameterName , RouteValueDictionary values , RouteDirection routeDirection )
{
return httpContext.Request.IsLocal;
}
}
接着我们需要在注册的路由上使用该约束 只需要在constraints中初始化该约束类即可
constraints: new { LocalhostConstraint = new LocalhostConstraint ( ) }
区域路由
如果项目结构非常庞大就需要使用区域,可以把区域看成是项目的一个一个的子系统。右击项目-添加-区域即可创建一个区域,每个区域都包含了Controller、Model和View目录。比如以下创建了一个名称为FirstArea的区域,区域默认包含在代表全部区域的总目录Areas中,此后可以右击Areas目录来创建更多的区域。
区域路由地址中的段默认会加上区域的名称,如:
每个区域都配置有一个后缀为xxxRegistration的cs文件,这样的文件中都定义了一个派生自AreaRegistration类(区域基类)的子类,表示为一个区域。在区域类的RegisterArea方法中可以在当前区域下注册路由,如下面代码所示:
public class FirstAreaAreaRegistration : AreaRegistration
{
public override string AreaName
{
get => "FirstArea";
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute( //在当前区域注册路由
"FirstArea_default",
"FirstArea/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
在Global文件的Application_Start事件中默认使用了AreaRegistration的静态方法将所有单元路由进行了统一的初始化。
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start ( )
{
AreaRegistration.RegisterAllAreas ( );
//……
}
}
与单元路由有关联的类
AreaRegistration(单元路由)
此类表示为单元路由基类,我们在创建一个区域时就是在创建一个AreaRegistration的派生(上面例子中的FirstAreaAreaRegistration)。它提供一个RegisterAllAreas的静态方法,此方法会扫描并所有被当前项目所引用的程序集,查找所有从AreaRegistration派生的类型,然后利用反射将那些派生自AreaRegistration的类型缓存起来,同时会new出每一个单元路由的实例,这些实例都将被看成是AreaRegistration类型的变量。与此同时,RegisterAllAreas方法还会针对每一个单元路由实例创建它们所对应的AreaRegistrationContext实例,单元路由实例的RegisterArea方法需要一个AreaRegistrationContext作为参数以便注册路由,所以RegisterAllAreas创建出AreaRegistrationContext实例后会将其作为参数传递给对应的单元路由实例的RegisterArea方法。
//单元路由FirstAreaAreaRegistration的RegisterArea方法接收一个AreaRegistrationContext
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"FirstArea_default",
"FirstArea/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
AreaRegistrationContex(单元路由上下文)
AreaName
//区域的名称
Routes
//获取全局路由,包含区域路由,返回一个RouteCollection列表。注:如果在RegisterArea方法中通过AreaRegistrationContext直接获取路由列表的路由个数,则只返回Areas目录下所包含的全部区域路由个数,不包含非区域内的路由
//示例:
//在FirstArea区域下的Controller目录中创建了DefaultController并为DefaultController自定义了两个属性RouteList和RouteCount
namespace MVCArea.Areas.FirstArea.Controllers
{
public class DefaultController : Controller
{
public static System.Web.Routing.RouteCollection RouteList { get; set; }
public static int RouteCount { get; set; }
public ActionResult Index()
{
ViewData [ "RouteList" ] = RouteList.Count; //包含全局路由,区域路由的路由列表总个数
ViewData [ "RouteCount" ] = RouteCount; //只有Areas目录下所包含的全部区域路由个数
return View();
}
}
}
//在FirstAreaRegistration类的RegisterArea方法中通过AreaRegistrationContext访问路由列表
FirstArea.Controllers.DefaultController.RouteList = context.Routes; //返回全局路由和区域路由的路由列表,在外部调用RouteList.Count时会包含这些路由列表总个数
FirstArea.Controllers.DefaultController.RouteCount = context.Routes.Count; //在RegisterArea方法中则只返回Areas目录下所包含的全部区域路由个数
State
//一个object类型的用户自定义的对象,当在Global文件的Application_Start事件中执行AreaRegistration的重载方法RegisterAllAreas(object State)时,State将会赋值给创建出的AreaRegistrationContext的State属性
Namespaces
//这是一个只读的属性,该属性已经由ASP.NET MVC框架自动实现,用以当在全局路由列表中匹配上多个同名Controlle时将自动优先考虑AreaRegistrationContext所关联的区域下的Controller
MapRoute()
//在当前AreaRegistrationContext所关联的区域下注册一个区域性的路由
//示例:在区域类的RegisterArea方法中注册区域路由:
public override void RegisterArea ( AreaRegistrationContext context )
{
context.MapRoute (
name: "" ,
url: "FirstArea/{controller}/{action}/{id}" ,
defaults: new { action = "Index" , id = UrlParameter.Optional }
);
}
ASP.NET MVC - 路由
标签:索引 增加 new back 同名 route color 利用 全局
原文地址:http://www.cnblogs.com/myrocknroll/p/7615656.html