前面咱們介紹瞭如何實現一個能夠支持多站點不一樣URL轉換的Route,這裏咱們將實現一個繼承於SiteRouteBase的實例,也就是說,在這裏咱們將實例化第一個進行URL轉換的實例代碼。首先咱們先回顧一下平臺Route的工做機制:html
在找到站點後,系統會直接調用站點指定的URL轉換器的實例類,完成URL的轉換或組成可訪問的虛擬URL,首先,咱們先了解一下SiteRouteBasec#
/// <summary> /// 站點級URL解析基類 /// </summary> public abstract class SiteRouteBase { /// <summary> /// 分解URL獲得controller和action,將分解結果寫到 RouteData 中 /// </summary> /// <param name="accessURL">沒有SiteURL的訪問地址</param> /// <returns></returns> public abstract bool GetRouteData(RouteData data, string accessURL); /// <summary> /// 根據參數獲得外部訪問地址,與 GetRouteData 相對應 /// </summary> /// <param name="requestContext"></param> /// <param name="values"></param> /// <returns></returns> public abstract VirtualPathData GetVirtualPath(VonPortalRoute route, RequestContext requestContext, RouteValueDictionary values); }
public abstract bool GetRouteData(RouteData data, string accessURL);ide
這個是解釋虛擬URL到Controller/Action的轉換器,這裏移動有兩個參數,RouteData data,存放轉換結果,string accessURL是不含網站URL頭的訪問網址,例如:若是站點的URL爲 http://localhost:1234,當你訪問http://localhost:1234/Admin/UserList 時,系統在執行時根據URL頭http://localhost:1234信息就能夠找到實際的訪問站點了,並將地址進行截取,將站點的實際訪問信息,即「Admin/UserList」發送給站點URL轉換的實例類來處理。函數
這樣咱們就能夠創建多種實例類來解釋,例如:以斜線做爲分隔符的,也能夠如下劃線做爲分隔符的,一樣也能夠經過其餘方式進行的,從而完成不一樣站點不一樣解析的目的。網站
例如:http://localhost:1234/Admin/UserList 和 http://localhost:5555/Admin_UserList 訪問的內容是同樣的,只是訪問的URL表現是不同的,系統一樣會根據站點設置截取掉URL頭信息,將後面的訪問信息經過站點Route的實例,調用其GetRouteData函數完成URL的轉換,上述兩個網址若是是針對http://localhost:1234和 http://localhost:5555兩個網站的話,其調用Route實例的轉換函數就是GetRouteData(RouteData, "Admin/UserList")和GetRouteData(RouteData, "Admin_UserList")了,由轉換器本身來完成最終的解釋。spa
好了!咱們來實現第一個本身的Route:code
咱們先新建一個類工程
htm
using System.Collections.Generic; /// <![CDATA[author : jamesvon date : 2016.4.2]]> /// <summary> /// CAP URL轉換器,網址後以Controller爲第一路徑,Action爲第二路徑,後面緊隨執行參數,?後跟隨是頁面參數<br /> /// 例如:http://127.0.0.1/page/news/3232332.html?from=www.baidu.com <br /> /// 其中 http://127.0.0.1 爲域名區域,page 爲 Controller 名稱,news 爲 action 名稱,3232332 爲新聞序號參數,?後面跟得是頁面參數。 /// <remarks> /// 這是各類路由轉換器的一種,其基礎類是 SiteRouteBase </remarks> using System.Web.Routing; namespace VonPortal.Web { /// <summary> /// CAP URL轉換器,網址後以Controller爲第一路徑,Action爲第二路徑,後面緊隨執行參數,?後跟隨是頁面參數<br /> /// result.Values["controller"]=Controller名稱,若是沒有則是Home<br /> /// result.Values["action"]=Action名稱,若是沒有則是Index<br /> /// result.Values["item"]=執行參數,以String[]對象存儲,沒有則爲string[0]<br /> /// result.Values["param"]=頁面參數,以String[]對象存儲,沒有則爲string[0]<br /> /// result.Values["controller"]=Controller名稱 /// </summary> /// <example>http://127.0.0.1/news/view/221122.html?from=wwww.sina.com.cn</example> /// <seealso cref="SiteRouteBase"/> /// <![CDATA[This is a text]]> public class CAPRouter : SiteRouteBase { /// <summary> /// 解析一個URL /// </summary>> /// <param name="data">路由數據</param> /// <param name="accessURL">不含網站頭的訪問路徑</param> /// <returns>路由數據</returns> public override bool GetRouteData(RouteData data, string accessURL) { // [{controller}]/{action}[/{key}/{key_value}..]?{param_name}={param_value}[&{param_name}={param_value}..]\ accessURL = accessURL.Trim(new char[] { '/', ' ', '?', '&' }); int mPos = accessURL.IndexOf('?'); string[] path = mPos >= 0 ? accessURL.Remove(mPos).Split(new char[1] { '/' }) : accessURL.Split(new char[1] { '/' }); string[] param = mPos >= 0 ? accessURL.Substring(mPos + 1).Split(new char[2] { '&', '=' }): null; // write parameters to route datas. [{controller}]/{action}[/{key}/{key_value}..] int idx = 0; if (path.Length > 0 && path.Length % 2 == 0 && path[0] != "") { data.Values.Add("controller", path[idx]); idx++; } else data.Values.Add("controller", "Home"); if (path.Length > 0 && path.Length % 2 == 1 && path[0] != "") { data.Values.Add("action", path[0]); idx++; } else if (path.Length > 1 && path.Length % 2 == 0 && path[1] != "") { data.Values.Add("action", path[1]); idx++; } else data.Values.Add("action", "Index"); string key = ""; while (idx < path.Length) { if (key == "") key = path[idx]; else { data.Values.Add(key, path[idx]); key = ""; } idx++; } idx = 0; while (param != null && idx < param.Length) { if (key == "") key = param[idx]; else { data.Values.Add(key, param[idx]); key = ""; } idx++; } return true; } /// <summary> /// 獲得一個可訪問的虛擬路徑 /// </summary> /// <param name="route">系統路由</param> /// <param name="requestContext">訪問內容</param> /// <param name="values">執行參數</param> /// <returns>可訪問的虛擬路徑</returns> public override VirtualPathData GetVirtualPath(VonPortalRoute route, RequestContext requestContext, RouteValueDictionary values) { var elegantValues = new RouteValueDictionary(values); route.Url = "{controller}/{action}"; foreach(KeyValuePair<string, object> kv in values) { if (kv.Key == "site") continue; if (kv.Key == "area") continue; if (kv.Key == "controller") continue; if (kv.Key == "action") continue; if (route.Url.IndexOf("{" + kv.Key + "}") > 0) continue; route.Url += "/" + kv.Key + "/{" + kv.Key + "}"; } VirtualPathData data = route.BaseVirtualPath(requestContext, elegantValues); return data; } } }
在這裏咱們通個這個實例完成了第一個route的編寫。對象