步步為營-96-MyMVC2

說明:地址欄中的URL還存在一些不足之處

地址欄中最好能是http"www.sss.com/asdf/aaa

1.1 模擬路由的原理:創建Routing文件夾,并添加URLRoutingModule類

 

1.2:同時添加Route類和RouteTable類

 

 

下面主要寫看看路由是如何匹配的

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace YK.Simple.Mvc1.Routing
{
    public class Route
    {
        //構造函數
        public Route(string url, object defaults, Func<IDictionary<string, object>, IHttpHandler> handler)
        {
            UrlTemplate = url;
            Default = new Dictionary<string, object>();
            var defProps = defaults.GetType().GetProperties();
            foreach (var item in defProps)
            {
                Default.Add(item.Name, item.GetValue(defaults));
            }
            this.GetRouteHandler = handler;
        }
        //{controller}/{action}
        public string UrlTemplate { get; set; }
        //new {controller="Home",action="Index"}
        public IDictionary<string, object> Default { get; set; }

       // public IHttpHandler RouteHandler { get; set; }
        //public Func<IHttpHandler> GetRouteHandler { get; set; }
        public Func<IDictionary<string,object>, IHttpHandler> GetRouteHandler { get; set; }

        //讓路由規則主動匹配一個url,輸出一個包含路由對象的字典表
        public bool MatchRoute(string requestUrl, out IDictionary<string, object> routeDate)
        {
            //this.urlTemplate          and requestUrl
            //"{controller}/{action}"   and "sdfs/AsBb"
         
            routeDate = new Dictionary<string, object>();
            //為路由對象添加默認值
            foreach (var item in this.Default)
            {
                routeDate.Add(item.Key, item.Value);
            }
            var requestUrlItems = requestUrl.Split('/');//{"sdfs","AsBb"}
            var urlTemplates = this.UrlTemplate.Split('/'); //{"{controller}","{action}"}
            if (requestUrlItems.Length != urlTemplates.Length)
            {
                return false;
            }

            int ruCount = requestUrlItems.Length;
            //格式匹配成功,開始匹配每一個元素
            for (int i = 0; i < ruCount; i++)
            {
                var requestUrlItem = requestUrlItems[i];  //"sdfs"
                var urlTemplateItem = urlTemplates[i];  //"{controller}"
                if (urlTemplateItem.StartsWith("{") && urlTemplateItem.EndsWith("}"))
                {
                    var key = urlTemplateItem.Trim("{}".ToArray()); //"controller"
                    //判斷字典表中是否包含此對象
                    if (routeDate.ContainsKey(key))
                    {
                        routeDate[key] = requestUrlItem;
                    }
                    else 
                    {
                        routeDate.Add(key, requestUrlItem);
                    }
                }
                else
                {
                    //如果是"hello/{action}"這種形式,不是佔位符則需要進行強匹配
                    if (!urlTemplateItem.Equals(requestUrlItem, StringComparison.InvariantCultureIgnoreCase))
                    {
                        routeDate.Clear();
                        //該位置沒有匹配成功
                        return false;
                    }
                }
              
            }
            return true;

        }


    }
}
View Code

1.3 在路由表中 添加匹配路由的方法

 1.4 在MVC文件夾下添加RouteExt擴展方法用於獲取Handler

其中用到了一個類型需要自定義一下

這時候再來看global文件

 1.5 注意此時在擴展方法中是通過new MVCHandler()的方法創建的會出現資源沒有釋放的bug,這時候通過委託來實現

同時修改擴展方法

進一步修改,將路由數據通過參數傳入

下一步處理器中PR方法的寫法

最後配置一下config文件

 運行效果:

 

posted @ 2017-12-03 10:11  逍遥小天狼  阅读(165)  评论(0编辑  收藏  举报