宝哥软件园

分析Asp.Net路由系统的实现原理

编辑:宝哥软件园 来源:互联网 时间:2021-09-06

对于Asp.Net网络表单应用程序,请求的Url对应于一个特定的物理文件。这个网址与特定的物理文件紧密绑定,带来了很多便利性限制:可读性、SEO优化等等。为了解决这些局限性,微软引入了URL路由系统。这里有一个演示来分析Asp.Net的路由系统。

创建一个空的网络表单应用程序,并在Global.asax.cs文件中添加以下代码:

公共类global:系统。web . httpapplication { protected void application _ start(对象发送方,eventargse){//处理匹配的文件route table . routes . route existing files=true;//url默认值routeevaluatedictionary defaults=new routeevaluatedictionary(){ { ' name ',' wuwenmao'},{'id ',' 001 ' } };//route constraint route evaluatedictionary constraints=new route evaluatedictionary(){ ' name ',@' w {2,10}'},{'id ',@ ' d { 3 } ' }//与路由相关的值,但不参与路由是否与URL模式匹配routeevaluatedictionary数据标记=new routeevaluatedictionary(){ { ' default name ',' wuwenmao'},{'default id ',' 001 ' } };可路由。Routes.MapPageRoute('default ',' employees/{name}/{id} ',' ~/Default.aspx ',false,defaults,constraints,dataTokens}}使用以下页面代码创建名为“默认”的新网络表单页面:

% @ Page Language=' c# ' AutoEventWireup=' true ' code before=' default . aspx . cs ' Inherits=' webapplication 2。默认的“%!DOCTYPE html html xmlns=' http://www . w3 . org/1999/XHTML ' head runat=' server ' meta http-equiv=' Content-Type ' Content=' text/html;charset=utf-8 '/title/title/head body表单id=' form1 ' runat=' server这是div routedata中的Default.aspx页面/H1值:ul % foreach(route data . values中的var值){ % Li %=value . key %=%=value . value %/Li % } %/在ul RouteData中,数据标记:ul % foreach(route data中的var值。数据令牌){%Li%=值。键%=%=值。value %/Li % } %/ul/div/form/body/html,输入路径如下三种,结果相同:

http://localhost :2947/员工/伍文茂/001

http://localhost :2947/员工/伍文茂

http://localhost :2947/员工/

原因是在注册路由时,为路由模板中的变量设置了默认值,所以以上三个URL是等价的。

回顾全局文件,注册路由时还会设置一个变量:

这是使用常规规则来限制路由模板中的变量值,请求url中对应的变量值只有匹配规则才能被正确请求,否则返回404错误。如果id值的长度大于3:

我们通过上面一个简单的例子体验了Asp.Net路由系统,我们将通过查看下面的源代码来分析Asp.Net路由系统的实现原理。

首先,当我们使用下面的语句在我们的全局文件中注册一条路由时,我们实际上是在向全局路由表添加一条路由。

使用反射器工具,我们可以看到:

现在有一个问题,Asp.Net注册路由后如何使用路由系统?实际上,Asp.Net路由系统通过注册一个HttpModule对象来拦截请求,然后动态地将其映射到HttpHandler对象来处理当前请求,最后通过HttpHandler对象来处理和响应请求。实际上,这个HttpModule就是urloutingmodule。当我们启动Asp.Net程序时,我们可以通过全局文件中的模块属性来验证它。从下面的截图可以看出,Modules属性包含已注册的httpmodules,包括urloutingmodule:

在这个UrlRoutingModule中,有哪些与路由相关的操作?让我们继续看源代码:

从上面的源代码查看中,我们可以看到当一个请求到来时,Asp.Net通过注册的UrlRoutingModule模块截取该请求,然后从全局路由表中寻找匹配的RouteData。如果找到,则根据HttpApplication获取对应的HttpHandler,然后映射到当前请求上下文,供后续管道事件处理当前请求。

让我们继续查看源代码,并分析UrlRoutingModule如何从全局路由表中获取RouteData:

从上面可以看出,在UrlRoutingModule中调用全局路由表的getRoutedata实际上是依次调用每个注册路由的GetRouteData,并返回第一个匹配的RouteData如果所有注册的路由都不匹配,则返回null。

让我们看看路由中的getRoutedata做了什么:

匹配方法:

通过依次调用路由的GetRouteData方法,可以在getRoutedata方法中完成以下操作:

1.调用ParsedRoute类型的Match方法,将请求Url与当前Route对象中注册的路由模板进行匹配。如果不匹配,则为空;直接返回。

2.如果请求Url与当前Route对象的路由模板匹配,则RouteData对象是公共的;

3.根据注册路由信息时定义的约束条件,检查当前请求Url是否通过,返回null如果失败;

4.为路由数据对象分配值和数据令牌;

5.返回RouteData对象;

此时,Asp。Net的路由系统已经基本分析过了,由于篇幅有限,还有很多细节无法一一分析。

总结:

通过以上分析,我们梳理了思路,总结了Asp.Net路由系统所做的工作。首先,我们在Global中注册了Route对象,然后通过在Asp.Net注册的HttpModule UrlRoutingModule截取请求Url。然后从全局路由表中依次调用路由对象的getRoutedata。将请求Url与注册的路由信息进行匹配,返回第一个匹配的路由数据,找出整个路由表。路由并返回null,最后返回404到前端页面。

以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。

更多资讯
游戏推荐
更多+