前面我们介绍了如何实现一个可以支持多站点不同URL转换的Route,这里我们将实现一个继承于SiteRouteBase的实例,也就是说,在这里我们将实例化第一个进行URL转换的实例代码。首先我们先回顾一下平台Route的工作机制:
在找到站点后,系统会直接调用站点指定的URL转换器的实例类,完成URL的转换或组成可访问的虚拟URL,首先,我们先了解一下SiteRouteBase
////// 站点级URL解析基类 /// public abstract class SiteRouteBase { ////// 分解URL得到controller和action,将分解结果写到 RouteData 中 /// /// 没有SiteURL的访问地址 ///public abstract bool GetRouteData(RouteData data, string accessURL); /// /// 根据参数得到外部访问地址,与 GetRouteData 相对应 /// /// /// ///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,当你访问 时,系统在执行时根据URL头http://localhost:1234信息就可以找到实际的访问站点了,并将地址进行截取,将站点的实际访问信息,即“”发送给站点URL转换的实例类来处理。
这样我们就可以建立多种实例类来解释,例如:以斜线作为分隔符的,也可以以下划线作为分隔符的,同样也可以通过其他方式进行的,从而完成不同站点不同解析的目的。
例如: 和 访问的内容是一样的,只是访问的URL表现是不一样的,系统同样会根据站点设置截取掉URL头信息,将后面的访问信息通过站点Route的实例,调用其GetRouteData函数完成URL的转换,上述两个网址如果是针对和 两个网站的话,其调用Route实例的转换函数就是GetRouteData(RouteData, "")和GetRouteData(RouteData, "")了,由转换器自己来完成最终的解释。
好了!我们来实现第一个自己的Route:
我们先新建一个类工程
using System.Collections.Generic;/// ////// CAP URL转换器,网址后以Controller为第一路径,Action为第二路径,后面紧随执行参数,?后跟随是页面参数
/// 例如:http://127.0.0.1/page/news/3232332.html?from=www.baidu.com
/// 其中 http://127.0.0.1 为域名区域,page 为 Controller 名称,news 为 action 名称,3232332 为新闻序号参数,?后面跟得是页面参数。////// 这是各种路由转换器的一种,其基础类是 SiteRouteBase using System.Web.Routing;namespace VonPortal.Web{ ////// CAP URL转换器,网址后以Controller为第一路径,Action为第二路径,后面紧随执行参数,?后跟随是页面参数 ///
/// result.Values["controller"]=Controller名称,如果没有则是Home
/// result.Values["action"]=Action名称,如果没有则是Index
/// result.Values["item"]=执行参数,以String[]对象存储,没有则为string[0]
/// result.Values["param"]=页面参数,以String[]对象存储,没有则为string[0]
/// result.Values["controller"]=Controller名称 ///http://127.0.0.1/news/view/221122.html?from=wwww.sina.com.cn ////// public class CAPRouter : SiteRouteBase { /// /// 解析一个URL /// > /// 路由数据 /// 不含网站头的访问路径 ///路由数据 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; } ////// 得到一个可访问的虚拟路径 /// /// 系统路由 /// 访问内容 /// 执行参数 ///可访问的虚拟路径 public override VirtualPathData GetVirtualPath(VonPortalRoute route, RequestContext requestContext, RouteValueDictionary values) { var elegantValues = new RouteValueDictionary(values); route.Url = "{controller}/{action}"; foreach(KeyValuePairkv 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的编写。