zoukankan      html  css  js  c++  java
  • MVC5-2 MVC的管道流与路由

    自定义Modue与Hander

    之前讲了管道流中的Module与Hndler。现在我们可以去自定义Module和Handler

    Module

    其实很简单,一共需要三个步骤

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

    clip_image001

    clip_image002

    Handler

    和自定义Module类似

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

    clip_image003

    clip_image004

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

     

    MVC管道

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

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

    clip_image005

    那么截获它的是UrlRoutingModule =>

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

    clip_image006

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

    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

  • 相关阅读:
    ios 开发证书制作
    iOS UILable 高度自适
    asp 中创建日志打印文件夹
    ios iphone、ipad启动画面尺寸
    ios 更改UITableview中Section的字体颜色
    Azure Blob 存储简介
    java追加文件
    java读取文件
    DNS原理及其解析过程
    单点登录原理与简单实现
  • 原文地址:https://www.cnblogs.com/LiangSW/p/5815874.html
Copyright © 2011-2022 走看看