管道处理模型三(摘抄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个固定事件的扩展。

猜你喜欢

转载自www.cnblogs.com/zcbk/p/12190509.html