MVC5-2 MVC的管道流与路由

自定义Modue与Hander

以前讲了管道流中的Module与Hndler。如今咱们能够去自定义Module和Handler web

Module

其实很简单,一共须要三个步骤 缓存

  • 定义一个类去继承IHttpModule。并实现接口,这里推荐类以Module结尾
  • 在Init方法中注册咱们所须要的事件,完成拦截器。
  • 在WebConfig的System.webServer节点中配置Modules

clip_image001

clip_image002

Handler

和自定义Module相似 app

  • 建立一个类去继承IHttpHandler接口,并实现接口。
  • 在ProcessRequest中进行作咱们须要的处理
  • 在WebConfig的system.webServer节点中配置hanlder

clip_image003

clip_image004

注:MVC也是这么去作的,注册了Mvc的Module和Mvc的Handler。 函数

 

MVC管道

MVC的路由也是经过Module去拦截,而后找到匹配的路由。而后拿到handler激活Controller。下面解析一下过程 this

在MVC中咱们在RouteConfig中配置路由。结构是这样的 url

clip_image005

那么截获它的是UrlRoutingModule => spa

=> 这个moudule如咱们自定义的同样,继承了IHttpModule。注册了事件 application.PostResolveRequestCache += new EventHandler(this.OnApplicationPostResolveRequestCache);。须要说明的 是,这里也有了缓存。只有第一次才会去执行 3d

clip_image006

=> RouteData routeData = this.RouteCollection.GetRouteData(context); 映入眼帘的是这段代码。GetRouterData就是去获取匹配的路由 blog

clip_image007

=> 而后看到了一个foreach,是的。foreach。按照个人观察,它是一个键值对。这里就知道了,为何经常使用的路由要放到前面。能够快速遍历到。这里的值是RouteBase,它是一个抽象类。具体的实现应该在子类里面。 继承

clip_image008

=> 继续会看到,获取了RouteHandler!。那么RouteHandler是什么呢。

clip_image009

=> 转到了MapRoute也就是咱们的定义路由方法,看到了一个MvcRouteHandler。再转到Route的构造函数

clip_image010

clip_image011

=> 能够看到他是一个IRouteHandler的实现!以前Module的图继续往下走,看到了调用了GetHttpHandler这个方法。能够看到其实它就至关于一个工厂。那么拿到的又是什么呢

clip_image012

=> 能够发现,返回了一个MvcHandler。它就是咱们的最终主角。这时候一系列操做就完成了,MvcHandler的ProcessRequest方法,下图是同步方法,这里拿到了IController。而后再Execute。 IController是ControllerBase类继承的接口,Execute中又调用了ExecuteCore方法。也就是Controller类的实现。到此管道结束

clip_image013

clip_image014

clip_image015

这张图就是MVC的管道总体流程

clip_image016

 

Route详解

咱们在定义了MapRoute后,到底放到了什么地方呢?又是怎么对值进行过滤的呢?道兄莫慌,下面一一分析。

注意,这里并无实践。由于断点一直下不去。因此引用了别人的图。待以后再实践吧

clip_image017

上图不难发现,除了MapRoute外还有IngoreRoute。 进入到Blobal中能够看到注册路由用的是RouteTable.Routes

RouteTable

=> Routes [RouteCollection]

先看MapRoute的建立

先是建立一个Route而后添加到了咱们的 routes [RouteCollection]中

Route route = new Route(url, new MvcRouteHandler()) {

Defaults = CreateRouteValueDictionaryUncached(defaults),

Constraints = CreateRouteValueDictionaryUncached(constraints),

DataTokens = new RouteValueDictionary()

};

ConstraintValidation.Validate(route);

if ((namespaces != null) && (namespaces.Length > 0))

{

route.DataTokens["Namespaces"] = namespaces;

}

routes.Add(name, route);

而后再去看IgnoreRoute的建立

是的没错。这里建立一个IgnoreRouteInternal,而后也添加到了Routes中。

IgnoreRouteInternal route = new IgnoreRouteInternal(url) {

Constraints = CreateRouteValueDictionaryUncached(constraints)

};

ConstraintValidation.Validate(route);

routes.Add(route);

那么问题来了,MVC是如何分别受支持和不被支持的路由呢?

还记得,咱们的Route的构造函数须要一个IRouteHandler。这个IgnoreRouteInternal则是Route的子类,那么它传入的是什么呢?

clip_image018

能够看到,是StopRoutingHandler,这就不难猜到了。回到UrlRoutingModule代码中,从下图能够发现,这里拿到了RouteHandler以后,进行了判断。若是是StopRoutingHandler则直接把请示打回去。

clip_image019

下面开始说参数验证,

MapRoute有几个重载,有这样一个参数,contraints。它能够对咱们的参数进行一些约束。

clip_image020

一个简单的玩法,这里对id这个参数进行了约束,使其必须是数字。不只是id,其它的片断也能够进行约束。

clip_image021

看一下源码,其实这个方法就是进行匹配。在ProcessConstraion中,拿到了IRouteConstrraint。若是咱们的表达式是strng,就进行正则匹配。

上面有一个Match。这个是最吊的自定义。

clip_image022

clip_image023

进行自定义约束玩玩

  • 须要继承自IRouteConstraint接口,并实现
  • 在MapRoute对参数进行传入约束实例

clip_image024

clip_image025

相关文章
相关标签/搜索