天天看點

建立自己的 MVC portal (四)

前面我們介紹了如何實作一個可以支援多站點不同URL轉換的Route,這裡我們将實作一個繼承于SiteRouteBase的執行個體,也就是說,在這裡我們将執行個體化第一個進行URL轉換的執行個體代碼。首先我們先回顧一下平台Route的工作機制:

建立自己的 MVC portal (四)

在找到站點後,系統會直接調用站點指定的URL轉換器的執行個體類,完成URL的轉換或組成可通路的虛拟URL,首先,我們先了解一下SiteRouteBase

    /// <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);

這個是解釋虛拟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")了,由轉換器自己來完成最終的解釋。

好了!我們來實作第一個自己的Route:

我們先建立一個類工程

建立自己的 MVC portal (四)
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的編寫。

版權聲明:本文為CSDN部落客「weixin_33936401」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。

原文連結:https://blog.csdn.net/weixin_33936401/article/details/92213244