• 管道处理模型三(摘抄cainong2005博客)


    六.MVC路由扩展

    路由扩展的三个层面

    1.在MapRoute层面扩展:

    Routes.MapRoute("TestStatic","Test/{action}",new {controller="Second"})

    只是添加url规则,HttpHandler根本就没有替换到。

    2.在Route层面扩展:

    先建立一个自己的route,MyRoute,这里要继承RouteBase:

    1.  
      /// <summary>
    2.  
          /// 直接扩展route,拒绝浏览器
    3.  
          /// </summary>
    4.  
          public class MyRoute : RouteBase
    5.  
          {
    6.  
              /// <summary>
    7.  
              /// 解析路由信息
    8.  
              /// </summary>
    9.  
              /// <param name="httpContext"></param>
    10.  
              /// <returns></returns>
    11.  
              public override RouteData GetRouteData(HttpContextBase httpContext)
    12.  
              {
    13.  
                  //如果是 Chrome浏览器 62.0.3202.94版本 ,则访问 Pipe/Refuse,此页面上只有一句话“<h2>拒绝chrome浏览器访问</h2>”,而其他浏览器不作限制
    14.  
                  if (httpContext.Request.UserAgent.IndexOf("Chrome/62.0.3202.94") >= 0)
    15.  
                  {
    16.  
                      RouteData rd = new RouteData(this, new MvcRouteHandler());
    17.  
                      rd.Values.Add("controller", "Pipe");
    18.  
                      rd.Values.Add("action", "Refuse");
    19.  
                      return rd;
    20.  
                  }
    21.  
                  return null;
    22.  
              }
    23.  
       
    24.  
       
    25.  
              /// <summary>
    26.  
              /// 指定处理的虚拟路径
    27.  
              /// </summary>
    28.  
              /// <param name="requestContext"></param>
    29.  
              /// <param name="values"></param>
    30.  
              /// <returns></returns>
    31.  
              public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    32.  
              {
    33.  
                  return null;
    34.  
              }
    35.  
          }
    //如果是 Chrome浏览器 62.0.3202.94版本 ,则访问 Pipe/Refuse,此页面上只有一句话“<h2>拒绝chrome浏览器访问</h2>”,而其他浏览器不作限制
                if (httpContext.Request.UserAgent.IndexOf("Chrome/62.0.3202.94") >= 0)
                {
                    RouteData rd = new RouteData(this, new MvcRouteHandler());
                    rd.Values.Add("controller", "Pipe");
                    rd.Values.Add("action", "Refuse");
                    return rd;
                }
                return null;
            }
    
    
            /// <summary>
            /// 指定处理的虚拟路径
            /// </summary>
            /// <param name="requestContext"></param>
            /// <param name="values"></param>
            /// <returns></returns>
            public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
            {
                return null;
            }
        }

    然后add到RouteCollection中去。

    1.  
      public class RouteConfig
    2.  
      {
    3.  
      public static void RegisterMyRoutes(RouteCollection routes)
    4.  
      {
    5.  
      routes.Add(new MyRoute());
    6.  
      }
    7.  
       
    8.  
      public static void RegisterMyMVCHandler(RouteCollection routes)
    9.  
      {
    10.  
      routes.Add(new Route("Eleven/{*Info}", new ElevenRouteHandler()
    11.  
      ));
    12.  
      }
    13.  
       
    14.  
      public static void RegisterRoutes(RouteCollection routes)
    15.  
      {
    16.  
      routes.IgnoreRoute("{resource}.axd/{*pathInfo}");//忽略路由
    17.  
      //routes.IgnoreRoute("test/{*pathInfo}");
    18.  
      //mvc路由规则下的扩展
    19.  
      routes.IgnoreRoute("Handler/{*pathInfo}");
    20.  
       
    21.  
      routes.MapRoute(
    22.  
      name: "Default",
    23.  
      url: "{controller}/{action}/{id}",
    24.  
      defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
    25.  
      namespaces: new string[] { "Ruanmou.MVC5.Controllers" }
    26.  
      );
    27.  
       
    28.  
      }
    29.  
      }
    public static void RegisterMyRoutes(RouteCollection routes)
    {
    routes.Add(new MyRoute());
    }
    
    public static void RegisterMyMVCHandler(RouteCollection routes)
    {
    routes.Add(new Route("Eleven/{*Info}", new ElevenRouteHandler()
    ));
    }
    
    public static void RegisterRoutes(RouteCollection routes)
    {
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");//忽略路由
    //routes.IgnoreRoute("test/{*pathInfo}");
    //mvc路由规则下的扩展
    routes.IgnoreRoute("Handler/{*pathInfo}");
    
    routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
    namespaces: new string[] { "Ruanmou.MVC5.Controllers" }
    );
    
    }
    }

    注意,这里没有用routes.MapRoute方法,直接用add,为什么可以这样用,还是看MapRoute方法:

    自定义的路由也要在global注册

    1.  
      protected void Application_Start()
    2.  
      {
    3.  
      AreaRegistration.RegisterAllAreas();//注册区域路由
    4.  
      GlobalConfiguration.Configure(WebApiConfig.Register);//注册webapi路由
    5.  
      FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);//
    6.  
       
    7.  
      RouteConfig.RegisterMyMVCHandler(RouteTable.Routes);
    8.  
      RouteConfig.RegisterMyRoutes(RouteTable.Routes);
    9.  
      RouteConfig.RegisterRoutes(RouteTable.Routes);//注册路由
    10.  
      BundleConfig.RegisterBundles(BundleTable.Bundles);
    11.  
      ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory());//替换默认的控制器工厂
    12.  
      }

    好了,运行一下吧

    从图上可以看到,因为在route上扩展了新的路由规则,遇到chrome浏览器就跳到refuse页面,达到了拒绝chrome浏览器的效果,但对于其他浏览器还正常显示。

    针对移动端、PC端用哪个控制器,中文、英文环境用哪个控制器,用户登录了跳到哪里去,没登录跳到哪里去,就可以在route层面上扩展,可以随意定义规则,因为能拿到context,有了上下文就有了全世界。

    3.扩展Handler,不一定是MvcHandler

    1.  
      /// <summary>
    2.  
      /// 扩展IRouteHandler,
    3.  
      /// 扩展IHttpHandler
    4.  
      /// </summary>
    5.  
      public class ElevenRouteHandler : IRouteHandler
    6.  
      {
    7.  
      public IHttpHandler GetHttpHandler(RequestContext requestContext)
    8.  
      {
    9.  
      return new ElevenHttpHandler(requestContext);
    10.  
      }
    11.  
      }
    12.  
       
    13.  
      /// <summary>
    14.  
      /// 还是我们熟悉的handler
    15.  
      /// </summary>
    16.  
      public class ElevenHttpHandler : IHttpHandler
    17.  
      {
    18.  
      public ElevenHttpHandler(RequestContext requestContext)
    19.  
      {
    20.  
      Console.WriteLine("构造ElevenHandler");
    21.  
      }
    22.  
       
    23.  
      public void ProcessRequest(HttpContext context)
    24.  
      {
    25.  
      string url = context.Request.Url.AbsoluteUri;
    26.  
      context.Response.Write(string.Format("这里是Eleven定制:{0}", this.GetType().Name));
    27.  
      context.Response.Write((string.Format("当前地址为:{0}", url)));
    28.  
       
    29.  
      context.Response.End();
    30.  
      }
    31.  
       
    32.  
      public virtual bool IsReusable
    33.  
      {
    34.  
      get
    35.  
      {
    36.  
      return false;
    37.  
      }
    38.  
      }
    39.  
      }
    ElevenRouteHandler : IRouteHandler
    {
    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
    return new ElevenHttpHandler(requestContext);
    }
    }
    
    /// <summary>
    /// 还是我们熟悉的handler
    /// </summary>
    public class ElevenHttpHandler : IHttpHandler
    {
    public ElevenHttpHandler(RequestContext requestContext)
    {
    Console.WriteLine("构造ElevenHandler");
    }
    
    public void ProcessRequest(HttpContext context)
    {
    string url = context.Request.Url.AbsoluteUri;
    context.Response.Write(string.Format("这里是Eleven定制:{0}", this.GetType().Name));
    context.Response.Write((string.Format("当前地址为:{0}", url)));
    
    context.Response.End();
    }
    
    public virtual bool IsReusable
    {
    get
    {
    return false;
    }
    }
    }

    RouteConfig.cs:

    1.  
      /// <summary>
    2.  
      /// 路由配置
    3.  
      /// </summary>
    4.  
      public class RouteConfig
    5.  
      {
    6.  
      public static void RegisterMyRoutes(RouteCollection routes)
    7.  
      {
    8.  
      routes.Add(new MyRoute());
    9.  
      }
    10.  
       
    11.  
      public static void RegisterMyMVCHandler(RouteCollection routes)
    12.  
      {
    13.  
      routes.Add(new Route("Eleven/{*Info}", new ElevenRouteHandler()));
    14.  
      }
    15.  
       
    16.  
      public static void RegisterRoutes(RouteCollection routes)
    17.  
      {
    18.  
      routes.IgnoreRoute("{resource}.axd/{*pathInfo}");//忽略路由
    19.  
      //routes.IgnoreRoute("test/{*pathInfo}");
    20.  
      //mvc路由规则下的扩展
    21.  
      routes.IgnoreRoute("Handler/{*pathInfo}");
    22.  
       
    23.  
      routes.MapRoute(
    24.  
      name: "Default",
    25.  
      url: "{controller}/{action}/{id}",
    26.  
      defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
    27.  
      namespaces: new string[] { "Ruanmou.MVC5.Controllers" }
    28.  
      );
    29.  
       
    30.  
      }
    31.  
      }
    public static void RegisterMyMVCHandler(RouteCollection routes)
    {
    routes.Add(new Route("Eleven/{*Info}", new ElevenRouteHandler()));
    }
    
    public static void RegisterRoutes(RouteCollection routes)
    {
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");//忽略路由
    //routes.IgnoreRoute("test/{*pathInfo}");
    //mvc路由规则下的扩展
    routes.IgnoreRoute("Handler/{*pathInfo}");
    
    routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
    namespaces: new string[] { "Ruanmou.MVC5.Controllers" }
    );
    
    }
    }

    然后在global中注册:

    1.  
      protected void Application_Start()
    2.  
      {
    3.  
      AreaRegistration.RegisterAllAreas();//注册区域路由
    4.  
      GlobalConfiguration.Configure(WebApiConfig.Register);//注册webapi路由
    5.  
      FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);//
    6.  
       
    7.  
      RouteConfig.RegisterMyMVCHandler(RouteTable.Routes);
    8.  
      RouteConfig.RegisterMyRoutes(RouteTable.Routes);
    9.  
      RouteConfig.RegisterRoutes(RouteTable.Routes);//注册路由
    10.  
      BundleConfig.RegisterBundles(BundleTable.Bundles);
    11.  
      ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory());//替换默认的控制器工厂
    12.  
      }
    RouteConfig.RegisterMyMVCHandler(RouteTable.Routes);
    RouteConfig.RegisterMyRoutes(RouteTable.Routes);
    RouteConfig.RegisterRoutes(RouteTable.Routes);//注册路由
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory());//替换默认的控制器工厂
    }

    运行一下,

    为什么可以做到呢?

    所以上面的流程就是,先建立一个RegisterMyMVCHandler的路由规则,指定它的RouteHandler为ElevenRouteHandler,然后通过ElevenRouteHandler又找到了ElevenHttpHandler,而ElevenHttpHandler里面的功能就是打印了两句话。

    到了这个层面后,在例子中我们只是打印了两句话,但是可以做的扩展就多了,可以在ProcessRequest方法中版权申明,或者做一些留后门的事情,获取dll文件,获取webconfig信息,甚至得到数据库数据,想干嘛就干嘛。(好恐怖)

    所以,管道处理模型的核心:多个HttpModule以及HttpHandler对25个固定事件的扩展。

  • 相关阅读:
    【iOS】找工作的面试题集锦
    APP项目优化--启动速度优化篇
    【Swift】Timer定时器到底准不准确?
    leetcode刷题 495~
    leetcode刷题 464~
    leetcode刷题 441~
    leetcode刷题 420~
    leetcode刷题 396~
    leetcode刷题 373~
    leetcode刷题 307~
  • 原文地址:https://www.cnblogs.com/zcbk/p/12190509.html
Copyright © 2020-2023  润新知