創建本身的 MVC portal (四)

前面咱們介紹瞭如何實現一個能夠支持多站點不一樣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的編寫。對象

相關文章
相關標籤/搜索