前面我們介紹了如何實作一個可以支援多站點不同URL轉換的Route,這裡我們将實作一個繼承于SiteRouteBase的執行個體,也就是說,在這裡我們将執行個體化第一個進行URL轉換的執行個體代碼。首先我們先回顧一下平台Route的工作機制:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5iM4EDOwMjMfZzUmh2X5QzNwgTMvwFNwUDMvwlNxAjMvwVZjFGcz9CXzRWYvxGc19CX0VmbuEmbph2Yz9mLjlGdhR3cvw1LcpDc0RHaiojIsJye.png)
在找到站點後,系統會直接調用站點指定的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:
我們先建立一個類工程
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