手机版

ASP.NET路由模型工作原理分析

时间:2021-11-05 来源:互联网 编辑:宝哥软件园 浏览:

这是给ASP的。 NET 4.5版。最新的5.0版本中似乎加入了OWIN,它完全解除了与Web服务器的耦合。我还没有研究过,不敢假设4.5模式适用于5.0。

动作*0x1:大话ASP.NET模式。

首先,让我们了解下一个请求的命运,看看它一生走过的曲折道路。如下图所示:

在上图的美图中,我们可以看到一个“请求”从客户端浏览器开始,通过钱山、HTTP到达服务器。服务器的核心模块SYS热情招待。简单装饰了一下,就告别了,因为HTTP。SYS知道这是一个带着梦想的“请求”,应该去哪里就去哪里,所以。

IIS是一片神奇的土地,那里有一位伟大的神名叫inetinfo.exe,所以他去了神的住所W3SVC service (windows service),希望能给他一些指示。神仙通过查阅天书(IIS配置文件)知道这不是一个普通的静态文件,所以不能直接发回,应该去自己人办的加工厂(也就是在对应网站的工作过程中)好好研究一下。

加工厂现任老板W3wp.exe在IIS6之前是aspnet_wp.exe,他被辞退是因为他没有很好的管理加工厂之间的站点问题(asp.net_wp.exe用一个进程托管所有的网站,用应用领域划分,导致网站之间互相影响)。现任老板w3wp.exe通过一个网站一个流程解决了问题,所以他顺利上台。

进入加工厂的“请求”访问了门卫asp.net_isapi.dll,门卫发现是第一个“请求”过来的,于是为其打开了工厂的生产车间(也就是第一个请求到达时,asp.net运行环境已经启动,以后的请求可以直接进入这个环境。),并让车间主任ISAPIRuntime负责。主管高兴地表示欢迎(即ISAPIRuntime调用ProcessRequest (PR)方法访问当前请求所在的ecb句柄),并将其换成统一的服装HttpWorkRequest(即简单打包请求),然后调用monitor HttpRuntime让monitor安排其工作。

班长说:“车间里有危险。你应该先穿上你的安全制服HttpContext。”(即通过PR方法将HttpWorkRequest封装到HttpContext中),然后我去组长宿舍(HttpApplicationFactory)调用一个组长(HttpApplication)来领导它。结果发现还没有组长,班长只好招了一个新组长。

每个组长都要经过严格的培训才能上岗。首先他要熟悉工厂进入指南Global.asax(即先编译Global.asax文件),然后通过指南中Application_Start方法的测试(即调用application _ start方法),这样才能成为一代团队的领导者。每个新组长首先要做的就是把所有的车间模块组装起来,创建一个好的车间流水线(通过读取配置文件,加载所有的IHttpModule并调用它们的Init方法,一般用于注册流水线事件,然后通过BuidStepManager方法按照经典模式或者集成模式生成对应的StepManager)。

新组长看到“请求”后,二话没说立即启动车间流水线,扔了进去。安全统一的HttpContext的“请求”应该依次经过管道(ASP.NET管道模型)中的所有层次,其中第7层之后生成一个IHttpHandler类型的对象,第11层之后执行该对象的ProcessRequest方法处理该请求,其中“请求”被完美的处理和成型,生成一个HttpResponse。通过剩下的管道后,梦的请求沿着原路返回。上图中的第11个和第12个事件描述了WebForm的Page对象处理请求的过程(即页面生命周期)。

至此,一个请求人一生的起起落落都结束了。如果你想知道路由模块是如何工作的,请先按住个人字段,点击右下角的赞。

操作*0x2:路由模型解析。

通过上文我们知道组长超文本传送协议(Hyper Text Transport Protocol的缩写)应用程序对象会负责组装所有的IHttpModule,它是如何加载的呢?我们观察反编译的代码:

private void init modules(){ HttpModuleCollection modules=RuntimeConfig .GetAppConfig()。httpmodules。创建模块();HttpModuleCollection other=this .CreateDynamicModules();模块AppendCollection(其他);这个_ moduleCollection=模块;这个initmodulecommon();}RuntimeConfig .GetAppConfig()。httpmodules。创建模块();通过这行代码,我们可以清楚的发现它读取了运行时的配置文件,那么我们打开运行时的配置文件以观究竟。

果然在这里增加了一个系统。网址路由模块类型。接下来我们再用反编译工具看这个类型的源码:

如我们所料路由解析实现了ihttpmmodule接口,我们看看它的初始化方法干了些什么?

受保护的虚拟void Init(HttpApplication应用程序){if(应用程序。上下文。items[_ context key]==null){ 0应用程序。上下文。项[_上下文关键字]=_上下文关键字;应用程序post resolverequestcache=新事件处理程序(这. OnapplicationPostSolverequestcache);}}对第七个事件PostResolveRequestCache注册方法在应用程序后期解析请求缓存中,那么这个方法又是干啥的呢?

public virtual void post resolverequestcache(Httpcontextbase上下文){ route data route data=this .路线选择。GetRouteData(上下文);//匹配路由,得到匹配结果路线数据。if(路由数据!=null){ iRouteHandler RouteHandler=RouteData .RouteHandlerif(RouterHandler==null){ 0抛出新的InvalidOperationException(字符串。格式(文化信息.CurrentCulture,SR . GetString(' urlroutingmodule _ NoRouteHandler '),新对象[0]);}if(!(routeHandler是stopcroutinghandler)){请求上下文请求上下文=新的请求上下文(上下文,路由数据);语境request context=request contextihttphandler Httphandler=路由处理程序.GetHttpHandler(请求上下文);//获取处理当前请求的接口对象if(HttpHandler==null){ object[]args=new object[]{ RouterHandler .GetType()};引发新的InvalidOperationException(字符串。格式(文化信息.CurrentUICulture,SR . GetString(' urlRoutingmodule _ NoHttpHandler '),args));}if (httpHandler是UrlAuthFailureHandler){if(!表单验证模块.FormsAuthRequired){ 0抛出新的HttpException(0x191,SR . GetString(' assesse _ Denied _ description 3 ');}UrlAuthorizationModule .ReportUrlAuthorizationFailure(HttpContext .当前,这个);}else{context .RemapHandler(HttpHandler);//映射:用当前接口对象处理请求。}}}}代码已经加了注释,3步走:匹配路由获取处理当前请求的接口对象映射:用当前接口对象处理请求。之后会在第11、12个事件之间调用接口对象的一对方法处理当前请求。

我们再整理下思路:ASP .网先注册了路由解析模块,他就是一个实现了ihttpmmodule接口的类,其初始化方法就是在第七个事件上注册一个方法,该方法先匹配路由,如果匹配成功了,则用匹配结果路由数据中的接口对象映射到当前上下文中,这样在之后第11、12个事件之间就会调用这个接口对象处理请求。

那么问题来了路线对象是什么时候注入进去的,IHttpHandler对象又是谁?

还记得路由规则是怎么添加的吗?如下面代码所示:

公开课全球:系统网络。http应用程序{受保护的void Application _ Start(对象发送方,EventArgs e){ var defaults=new routeevaluatedictionary();默认值。添加(' name ',' *);//方式一://通过可路由的静态对象路线新增一个途径类型的对象可路由。路线。添加(“app”,新路线(“app/{name}”,默认值,新MyRouteHandler()));//方式二://通过可路由的静态对象路线的扩展方法新增一个路由规则可路由路线。MapPageRoute('default ',' app/{name} ',' ~/WebForm1.aspx ',false,defaults);}} 这是我们经常用的两种方式添加路由规则,方式一中有我们自己编写的MyRouteHandler类型的实例作为参数,其实就是通过路由处理接口返回一个接口对象。

///摘要///实现了路由处理接口的类型////摘要内部类MyRouteHandler : irouthandler { public IHttpHandler GetHttpHandler(请求上下文请求上下文){//返回一个页对象,用于处理请求返回新的web form 1();}} 其实这两种方式没有本质上的区别,因为方式二中路由规则参数都会实例化一个途径对象的。

我们分析方式二的源代码:

公共路由映射路由名称(字符串路由名称、字符串路由名称、字符串物理文件、bool检查物理值访问、路由评估预测默认值、路由评估预测约束、路由评估预测数据令牌){ if(路由器URL==null){ 0抛出新的ArgumentNullException('路由器URL ');}路线项目=新路线(路线、默认值、约束、数据令牌、新页面输出处理器(物理文件、检查物理值访问));这个。添加(routeName,项目);退货项目;} 发现所有的路由规则参数都用来实例化一个途径对象了,其中参数物理文件和checkPhysicalUrlAccess用来实例化寻呼机输出处理器对象了,其源码如下:

公共类页面路由处理程序: irouthandler { }这是一个实现了路由处理接口的类型,而这个接口只有一个作用就是返回接口对象,源码如下:

[从('系统)键入转发网络。路由,版本=3.5.0.0,区域性=中性,公钥标记=31bf 3856 ad 364 e 35')]公共接口irouthender {//method httphandler GetHttpHandler(请求上下文请求上下文);}到这里我们的疑问就解开了,原来我们注册的路由规则都实例化成了途径对象路线的GetRouteData方法用来匹配路由,路由规则中的物理文件和checkPhysicalUrlAccess用来实例化一个接口实例,用来处理请求。

总结:ASP .网的路由模型如下图所示

有关ASP .网路由模型工作原理小编就给大家介绍到这里,希望对大家有所帮助!

版权声明:ASP.NET路由模型工作原理分析是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。