ASP.NET 路由解析
这段时间在读园子里Artech大神的《ASP.NET MVC5框架揭秘》,慢慢地从底层了解了MVC模式的设计思路。下面是一些阅读的总结。
传统的Web Forms应用,URL指向的是具体的物理文件,而ASP.NET MVC应用一般指向的是某个Controller中的某个Action方法。URL与目标Controller/Action之间的映射关系是通过“路由”来实现的。
路由系统中的几个核心类的描述:
RouteBase
- 一个抽象基类。
public abstract class RouteBase
{
//.NET Framwork4.5以下无该属性(是否对物理文件采取路由)
public bool RouteExistingFiles { get; set; }
//获取路由数据
public abstract RouteData GetRouteData(HttpContextBase httpContext);
//路由解析生成一个完整的路径
public abstract VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values);
}
RouteData
- 封装了有关路由的信息。
- RouteData通过其RouteHandler属性返回一个RouteHandler对象。
- RouteHandler实现IRouteHandler中的GetHttpHandler(RequestContext requestContext),返回一个具的HttpHandler对象接管http请求。
public class RouteData
{
public RouteData();
public RouteData(RouteBase route, IRouteHandler routeHandler);
public string GetRequiredString(string valueName); public RouteBase Route { get; set; }
public IRouteHandler RouteHandler { get; set; }
public RouteValueDictionary DataTokens { get; }
public RouteValueDictionary Values { get; }
}
VirtualPathData
- 表示有关路由和虚拟路径的信息。
- 执行RouteBase的GetVirtualPath()会进行路由匹配,将路由变量去替换路由模板中的占位符并生成虚拟路径。
- 此类为虚拟路径和Route的封装。
public class VirtualPathData
{
public VirtualPathData(RouteBase route, string virtualPath);
public RouteValueDictionary DataTokens { get; }
public RouteBase Route { get; set; }
public string VirtualPath { get; set; }
}
Route
- 提供用于定义路由及获取路由相关信息的属性和方法。
- 路由解析由路由表中具体的某个Route对象来完成。
public class Route : RouteBase
{
public Route(string url, IRouteHandler routeHandler);
public Route(string url, RouteValueDictionary defaults, IRouteHandler routeHandler);
public Route(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler);
public Route(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler routeHandler);
//约束(可用正则)
public RouteValueDictionary Constraints { get; set; }
//存储额外的变量,不参与路由解析
public RouteValueDictionary DataTokens { get; set; }
public RouteValueDictionary Defaults { get; set; }
public IRouteHandler RouteHandler { get; set; }
public string Url { get; set; } public override RouteData GetRouteData(HttpContextBase httpContext);
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values);
}
RouteTable
- 存储应用程序的 URL 路由。
- 静态只读属性Routes访问全局路由表。
public class RouteTable
{
public static RouteCollection Routes { get; }
}
RouteCollection
- 一组Route的集合,用来操作Route。
- 调用RouteCollection的GetRouteData和GetVirtualPath时会遍历集合中的所有Route。
- 常用的两个方法。MapPageRoute:注册路由。Ignore:忽略对应的URL格式。
总结下类之间的关系:
Route对象代表一条实际的路由规则。调用Route对象的两个路由匹配方法时进行路由解析,返回的RouteData或VirtualPathData是对Route的封装。RouteTable存储了Web应用的全局路由信息,即多个Route对象。
路由注册
- MVC4中默认的路由注册
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
- 书中带约束的注册方式
public static void RegisterRoutes(RouteCollection routes)
{
//默认值
var defaults = new RouteValueDictionary{
{"areacode",""},{"days",}};
//正则约束
var constaints = new RouteValueDictionary {
{"areacode",@"0\d{2,3}"},{"days",@"[1-3]{1}"}};
//说明
var dataTokens = new RouteValueDictionary{
{"defaultCitr\y","BeiJing"},{"defaultDays",}};
routes.MapPageRoute("default","{areacode}/{}days","~/weather.aspx"
,false,defaults,constaints,dataTokens);
}
正则约束是其中一个比较简单的方法,我们还可以通过自定义约束来实现。实现IRouteConstraint的Match方法。
假设现在我们要通过IRouteConstraint来限制IE浏览器的访问。
public class IERouteConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
return !(httpContext.Request.UserAgent.Contains("MSIE"));
}
}
//在原来的约束基础上修改
var constaints = new RouteValueDictionary {
{"areacode",@"0\d{2,3}"},{"days",@"[1-3]{1}"},new IERouteConstraint()};
注:针对自定义路由约束的详细内容,请移步:http://www.cnblogs.com/xfrog/archive/2010/12/19/1910428.html。此例也选自该博文。
从HTTP请求到路由解析
- URLRoutingModule派生自IHttpModule。通过它注册HttpApplication的PostResolveRequestCache事件。
- 当一个HttpApplication对象触发该事件后,URLRoutingModule通过RouteTable的静态只读属性Routea得到全局的路由表的RouteCollection对象,然后根据当前的上下文创建一个HttpContextWrapper对象(派生自HttpContextBase),并将其作为参数调用RouteCollection对象的GetRouteData方法。
- 如果路由匹配成功,会返回一个具体的RouteData对象。
- URLRoutingModule会将HttpContextWrapper传入RouteData对象中的RouteHandler。调用它的GetHttpHandler方法,得到一个具体的HttpHandler。URLRoutingModule最后调用HttpContextWrapper对象的RemapHandler方法对得到的HttpHandler进行映射。
- 解析完成,针对当前的HTTP请求就由该Handler来接手。
注:本博文大多数内容来自《ASP.NET MVC5框架揭秘》中,只是做内容的梳理和总结。
ASP.NET 路由解析的更多相关文章
- ASP.NET路由模型解析
大家好,我又来吹牛逼了 ~-_-~ 转载请注明出处:来自吹牛逼之<ASP.NET路由模型解析> 背景:很多人知道Asp.Net中路由怎么用的,却不知道路由模型内部的运行原理,今天我就给大家 ...
- ASP.NET Web API路由解析
前言 本篇文章比较长,仔细思考阅读下来大约需要15分钟,涉及类图有可能在手机显示不完整,可以切换电脑版阅读. 做.Net有好几年时间了从ASP.NET WebForm到ASP.NET MVC再到ASP ...
- ASP.NET路由[ASP.NET Routing]
ASP.NET路由[ASP.NET Routing] ASP.NET路由允许你在使用URL时不必匹配到网站中具体的文件,因为这个URL不必匹配到一个文件,你使用了描述用户行为且更容易被用户理解的URL ...
- ASP.NET路由系统实现原理:HttpHandler的动态映射
我们知道一个请求最终通过一个具体的HttpHandler进行处理,而我们熟悉的用于表示一个Web页面的Page对象就是一个HttpHandler,被用于处理基于某个.aspx文件的请求.我们可以通过H ...
- ASP.NET Web API 框架研究 ASP.NET 路由
ASP.NET Web API 如果采用Web Host方式来寄宿,在请求进入Web API 消息处理管道之前,就会用ASP.NET 自身的路由系统根据注册的路由表,解析出当前请求的HttpContr ...
- MVC路由解析---UrlRoutingModule
文章引导 MVC路由解析---IgnoreRoute MVC路由解析---MapRoute MVC路由解析---UrlRoutingModule Area的使用 引言: 此文全文内容90%转自 一.前 ...
- AspNet Mvc 路由解析中添加.html 等后缀 出现404错误的解决办法
使用Mvc 有时候我们希望,浏览地址以.html .htm 等后缀名进行结尾. 于是我们就在RouteConfig 中修改路由配置信息,修改后的代码如下 routes.IgnoreRoute(&quo ...
- ASP.NET 路由
URL 模式可以包含文本值和变量占位符(也称为“URL 参数”). 文本和占位符位于由斜杠 (/) 字符分隔的 URL 段中. 当生成请求时,URL 分析为段和占位符,变量值提供给请求处理程序. ...
- ASP.NET路由
ASP.NET 路由使您可以使用不必映射到网站中特定文件的 URL. 由于该 URL 不必映射到文件,因此可以使用对用户操作进行描述因而更易于被用户理解的 URL. ASP.NET MVC 框架和 A ...
随机推荐
- Linux下多路径multipath配置
一.multipath在redhat 6.2中的基本配置: 1. 通过命令:lsmod |grep dm_multipath 检查是否正常安装成功.如果没有输出说明没有安装那么通过yum功能安装一下 ...
- ORACLE基本知识
一.数据库名 什么是数据库名? 数据库名就是一个数据库的标识,就像人的身份证号一样.他用参数DB_NAME表示,如果一台机器上装了多全数据库,那么每一个数据库都有一个数据库名.在数据库安装或创建完成 ...
- ieee80211w
80211w概述 1, WLAN网络在设计的时候就容易遭受各种类型的Denial of Service(DOS)攻击, a, 射频干扰(RF jamming) b, Spoofed Disconnec ...
- [.NET领域驱动设计实战系列]专题十:DDD扩展内容:全面剖析CQRS模式实现
一.引言 前面介绍的所有专题都是基于经典的领域驱动实现的,然而,领域驱动除了经典的实现外,还可以基于CQRS模式来进行实现.本专题将全面剖析如何基于CQRS模式(Command Query Respo ...
- 一个空行引起的阿里云负载均衡上部署https证书的问题
今天在阿里云上购买了WoSign的https证书,在证书签发后,在控制台下载证书文件,一共有2个文件,一个是.key文件(私钥文件),一个是.pem文件(证书文件). 然后在阿里云负载均衡“证书管理” ...
- CQRS\ES架构介绍
大家好,我叫汤雪华.我平时工作使用Java,业余时间喜欢用C#做点开源项目,如ENode, EQueue.我个人对DDD领域驱动设计.CQRS架构.事件溯源(Event Sourcing,简称ES). ...
- 【C语言学习】《C Primer Plus》第2章 C语言的概述
学习总结 1.#include是C预处理命令之一,#include指向的是头文件,如#include <stdio.h>,这个stdio.h就是程序需要引用的C标准库之一.里面包含了pri ...
- 我所了解的CSS
我真的了解css吗? 我这样问自己. 我的思考和这几天的学习来自于看了寒冬winter大神的这篇blog:谈谈面试与面试题 .说实话, 我边看,脑袋里面边翻篇一样的过着我的那点css知识,看完了,整个 ...
- 搭建hadoop1.2集群
环境准备 我使用的是vmware workstation,首先安装ubuntu 12.04,安装完成后通过vmware的clone,clone出两个虚机,设置的IP分别是: 192.168.74.13 ...
- ubuntu:solve the problem of 'E:Problem with MergeList /var/lib/apt/lists/'
just run this command: sudo rm /var/lib/apt/lists/* -vfR it will remove all the software package wit ...