說明:地址欄中的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; } } }
1.3 在路由表中 添加匹配路由的方法
1.4 在MVC文件夾下添加RouteExt擴展方法用於獲取Handler
其中用到了一個類型需要自定義一下
這時候再來看global文件
1.5 注意此時在擴展方法中是通過new MVCHandler()的方法創建的會出現資源沒有釋放的bug,這時候通過委託來實現
同時修改擴展方法
進一步修改,將路由數據通過參數傳入
下一步處理器中PR方法的寫法
最後配置一下config文件
運行效果: