zoukankan      html  css  js  c++  java
  • 6.自定义路由

    1.路由学习

    2.路由源码解读

    3.自定义路由

    前面学习了这么多,那么我手也有点痒了,那么就来把路由扩展一下,看看到底能做多少事情(到底能做什么?其实我也不知道,毕竟还没在项目中使用过,能带来多大好处,也不是很清楚,虽然知道理论,但是不知道如何把学习的理论价值最大化,其实也是挺可悲的,不说了,干活吧!!!)

    既然要扩展路由,那么我们肯定是需要一个路由的,那么如何弄一个路由出来了?前面也说过了,我们需要继承一下路由的基类RouteBase

    我们来看看RouteBase的源码:

    namespace System.Web.Routing
            {
                [TypeForwardedFrom("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
                public abstract class RouteBase
                {
                    private bool _routeExistingFiles = true;
    
                    public bool RouteExistingFiles
                    {
                        get
                        {
                            return this._routeExistingFiles;
                        }
                        set
                        {
                            this._routeExistingFiles = value;
                        }
                    }
    
                    public abstract RouteData GetRouteData(HttpContextBase httpContext);
    
                    public abstract VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values);
                }
            }
    View Code

    我们再来看看框架是如何实现的,Route源码如下:

    public override RouteData GetRouteData(HttpContextBase httpContext)
            {
                string virtualPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2) + httpContext.Request.PathInfo;
                RouteValueDictionary routeValueDictionary = this._parsedRoute.Match(virtualPath, this.Defaults);
                if (routeValueDictionary == null)
                {
                    return null;
                }
                RouteData routeData = new RouteData(this, this.RouteHandler);
                if (!this.ProcessConstraints(httpContext, routeValueDictionary, RouteDirection.IncomingRequest))
                {
                    return null;
                }
                foreach (KeyValuePair<string, object> current in routeValueDictionary)
                {
                    routeData.Values.Add(current.Key, current.Value);
                }
                if (this.DataTokens != null)
                {
                    foreach (KeyValuePair<string, object> current2 in this.DataTokens)
                    {
                        routeData.DataTokens[current2.Key] = current2.Value;
                    }
                }
                return routeData;
            }
    
            public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
            {
                BoundUrl boundUrl = this._parsedRoute.Bind(requestContext.RouteData.Values, values, this.Defaults, this.Constraints);
                if (boundUrl == null)
                {
                    return null;
                }
                if (!this.ProcessConstraints(requestContext.HttpContext, boundUrl.Values, RouteDirection.UrlGeneration))
                {
                    return null;
                }
                VirtualPathData virtualPathData = new VirtualPathData(this, boundUrl.Url);
                if (this.DataTokens != null)
                {
                    foreach (KeyValuePair<string, object> current in this.DataTokens)
                    {
                        virtualPathData.DataTokens[current.Key] = current.Value;
                    }
                }
                return virtualPathData;
            }
    View Code

    我们仿照框架实现方法,代码如下:

    /// <summary>
        /// 自定义路由
        /// </summary>
        public class MyRoute : RouteBase
        {
            /// <summary>
            /// 返回我们定义的路由信息
            /// </summary>
            /// <param name="httpContext"></param>
            /// <returns></returns>
            public override RouteData GetRouteData(HttpContextBase httpContext)
            {
                //可以省略此句话(父类默认为true),为true表示应用此路由去处理所有请求(甚至包括与现有文件匹配的请求),为false,那么就不应用此路由
                base.RouteExistingFiles = true;
    
                // 封装有关路由的信息。(这里我使用MVC自带的对路由请求的处理机制)
                RouteData routeData = new RouteData(this,new MvcRouteHandler());
                //获取存储路由的字典
                RouteValueDictionary dictionary =  routeData.Values;
                //添加自定的路由到字典中
                dictionary.Add("controller", "Home");
                dictionary.Add("action", "Index");
                return routeData;
             }
    
            /// <summary>
            /// 表示有关路由和虚拟路径的信息,该路由和虚拟路径是在使用 ASP.NET 路由框架生成 URL 时产生的。
            /// </summary>
            /// <param name="requestContext"></param>
            /// <param name="values"></param>
            /// <returns></returns>
            public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
            {
                return null;
            }
        }

    注意:

      1.这里面有一个HttpContextBase参数,我在上面没有并没有使用,但是并不代表没用,其实用处非常大,例如:检查ip,浏览器类型,参数等等

      2.因为我们还是使用MVC自带的处理机制,所以还是会走控制器中的动作,如果我们自定义处理机制,那么就不会走控制器中的动作(可以调试一下),也就不会返回视图

        MVC的是使用虚拟路径来访问的,而我们自己写的其实是请求的物理文件

    视图代码如下:

    @{
        Layout = null;
    }
    
    <!DOCTYPE html>
    
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>Index</title>
    </head>
    <body>
        <div> 
            <h1>我是Home/Index页面 </h1>
        </div>
    </body>
    </html>
    View Code

    url:http://localhost:8955/

    其实我们完全可以自定义对路由的处理机制,代码如下:

    RouteData routeData = new RouteData(this,new MyRouteHandle());
       /// <summary>
        /// 处理匹配路由模式的请求的协定
        /// </summary>
        public class MyRouteHandle : IRouteHandler
        {
            public IHttpHandler GetHttpHandler(RequestContext requestContext)
            {
                return new MyHandler();
            }
        }
    
        /// <summary>
        /// 自定义 HTTP 处理程序同步处理 HTTP Web 请求而实现的协定。
        /// </summary>
        public class MyHandler : IHttpHandler
        {
            /// <summary>
            /// 获取一个值,该值指示其他请求是否可以使用 System.Web.IHttpHandler 实例。
            /// </summary>
            public bool IsReusable => true;
    
            /// <summary>
            /// 通过实现 System.Web.IHttpHandler 接口的自定义 HttpHandler 启用 HTTP Web 请求的处理。
            /// </summary>
            public void ProcessRequest(HttpContext context)
            {
                context.Response.ContentEncoding = Encoding.UTF8;
                context.Response.Write("我是Home/Index页面2");
                context.Response.Write(context.Request.Headers);
            }
        }

     显示效果如下:

    url:http://localhost:8955/

  • 相关阅读:
    动易CMS 实现ctrl+v粘贴图片并上传、word粘贴带图片
    帝国CMS 实现ctrl+v粘贴图片并上传、word粘贴带图片
    php大文件上传(切片)工具
    php大文件上传(分块)
    php大文件上传(分片)
    Nginx大文件上传(切片)
    百度WebUploader大文件上传(切片)
    WebUploader大文件上传(切片)
    html5大文件上传(切片)
    jquery大文件上传(切片)
  • 原文地址:https://www.cnblogs.com/zjdbk/p/10632347.html
Copyright © 2011-2022 走看看