建立自己的 MVC portal (三)
2016-05-04 00:00
197 查看
摘要: 建立自己的Router
下面我们来建立自己的Router体系:
这张图清晰地讲述了.net 访问过程中内部流程机制,当然我们也可以通过Global.asxm中建立相应的过程进行跟踪,来验证流程的真实性。我们可以关注其中的Routing节点部分,.net正式基于这个原理实现Router的,.net将RoutData与HttpContext合并成为RequestContext传递到IRoutHandler接口,IRoutHandler接口的实现类MvcRouteHandler接口到RequestContext参数,返回一个MvcHandler对象,并且为这个对象赋值RequestContext。
这个接口的定义是在 App_Start 中的 RouteConfig.cs 定义完成的。
我们先看下系统默认的Route代码:
我们要对他进行改造的目的是为了更好的配合系统的多站点的要求,也就是说为了满足不同站点使用不同Router的可能,我们需要重新构建自己的Route,那么我们就需要构建一个可根据站点不同,支持不同方案的Route机制。
为了达到这一目的,我们需要建立一个Router的基类,通过不同的实现方式来实现不同的站点的不同route的方法。
首先平台建立一个Route用来接收系统的调用,得到URL后首先分析这个URL指向的是哪个站点,知道了是哪个站点了我们就可以知道这个站点采用了何种方法来处理URL的转换,这样就可以实现不同站点不同URL转换的处理机制。
首先我们建立一个Router基类,来解决不同站点不同Router的机制问题:
我们要建立不同的SiteRouteBase实现方法来解决URL的实际转换,同时站点信息将实际使用的方法进行绑定就可以了,也就是说我们要建立一个Site(站点)信息,同时绑定SiteRouteBase的实现类就可以了,这里我先给一个简单代码样例,待以后具体实现:
我们要建立这个路由首先来研究一下Route的系统代码,系统的路由是从RouteBase继承过来的。
RouteBase里面主要需要实现两个主要函数,即
public abstract RouteData GetRouteData(HttpContextBase httpContext);
public abstract VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values);
只要我们重构这两个函数就可以了,当然这是一个可行的方案,但我们有更简单的方法来实现这个工作,就是我们可以从系统默认的路由来继承实现,Route是从RouteBase继承过来的。
这里我们省略了站点信息的系统缓存部分,即VonPortal.Web.GlobalValues.GetSiteByUrl(httpContext.Request.Url.AbsoluteUri)的代码,这段代码的含义就是根据访问的URL信息直接得到系统的站点信息site,如果没有得到则直接进入系统的Admin/SiteEdit进行新站点初始化。
下面我们来建立自己的Router体系:
这张图清晰地讲述了.net 访问过程中内部流程机制,当然我们也可以通过Global.asxm中建立相应的过程进行跟踪,来验证流程的真实性。我们可以关注其中的Routing节点部分,.net正式基于这个原理实现Router的,.net将RoutData与HttpContext合并成为RequestContext传递到IRoutHandler接口,IRoutHandler接口的实现类MvcRouteHandler接口到RequestContext参数,返回一个MvcHandler对象,并且为这个对象赋值RequestContext。
这个接口的定义是在 App_Start 中的 RouteConfig.cs 定义完成的。
我们先看下系统默认的Route代码:
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); }
我们要对他进行改造的目的是为了更好的配合系统的多站点的要求,也就是说为了满足不同站点使用不同Router的可能,我们需要重新构建自己的Route,那么我们就需要构建一个可根据站点不同,支持不同方案的Route机制。
为了达到这一目的,我们需要建立一个Router的基类,通过不同的实现方式来实现不同的站点的不同route的方法。
首先平台建立一个Route用来接收系统的调用,得到URL后首先分析这个URL指向的是哪个站点,知道了是哪个站点了我们就可以知道这个站点采用了何种方法来处理URL的转换,这样就可以实现不同站点不同URL转换的处理机制。
首先我们建立一个Router基类,来解决不同站点不同Router的机制问题:
/// <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); }
我们要建立不同的SiteRouteBase实现方法来解决URL的实际转换,同时站点信息将实际使用的方法进行绑定就可以了,也就是说我们要建立一个Site(站点)信息,同时绑定SiteRouteBase的实现类就可以了,这里我先给一个简单代码样例,待以后具体实现:
public class SiteInfo { public string Url{get;set;}//站点的URL头 public SiteRouteBase Translate{get;set;}//站点指定的Route的转换实例 }
我们要建立这个路由首先来研究一下Route的系统代码,系统的路由是从RouteBase继承过来的。
public abstract class RouteBase { protected RouteBase(); public bool RouteExistingFiles { get; set; } public abstract RouteData GetRouteData(HttpContextBase httpContext); public abstract VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values); }
RouteBase里面主要需要实现两个主要函数,即
public abstract RouteData GetRouteData(HttpContextBase httpContext);
public abstract VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values);
只要我们重构这两个函数就可以了,当然这是一个可行的方案,但我们有更简单的方法来实现这个工作,就是我们可以从系统默认的路由来继承实现,Route是从RouteBase继承过来的。
/// <summary> /// 平台Route /// </summary> public class VonPortalRoute : Route { public VonPortalRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler routeHandler) : base(url, defaults, constraints, dataTokens, routeHandler) { } public override RouteData GetRouteData(System.Web.HttpContextBase httpContext) { SiteInfo site = VonPortal.Web.GlobalValues.GetSiteByUrl(httpContext.Request.Url.AbsoluteUri); //根据 URL 得到对应的 Site,支持二级域名搜索 var data = new RouteData(this, new MvcRouteHandler());//声明一个RouteData,添加相应的路由值 if (site == null) //如果没有找到该域名,证明他是第一次被访问,则进入初始化界面 { data.Values.Add("controller", "Admin"); data.Values.Add("action", "SiteEdit"); } else { string accessUrl = httpContext.Request.Url.AbsoluteUri.Substring(site.SiteURL.Length); if (accessUrl.StartsWith("/")) accessUrl = accessUrl.Remove(0, 1); if (!site.Translater.GetRouteData(data, accessUrl)) return null; } data.Values.Add("site", site); return data; } public VirtualPathData BaseVirtualPath(RequestContext requestContext, RouteValueDictionary elegantValues) { return base.GetVirtualPath(requestContext, elegantValues); } public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) { SiteInfo site = (SiteInfo)requestContext.RouteData.Values["site"]; if (site == null) return new VirtualPathData(this, ""); else return site.Translater.GetVirtualPath(this, requestContext, values); } }
这里我们省略了站点信息的系统缓存部分,即VonPortal.Web.GlobalValues.GetSiteByUrl(httpContext.Request.Url.AbsoluteUri)的代码,这段代码的含义就是根据访问的URL信息直接得到系统的站点信息site,如果没有得到则直接进入系统的Admin/SiteEdit进行新站点初始化。
相关文章推荐
- 分享微信开发Html5轻游戏中的几个坑
- Windows Route 路由表命令整理
- C# MVC模式下商品抽奖功能实现
- Zend的MVC机制使用分析(二)
- ASP.NET MVC 4 捆绑和缩小实例介绍
- ASP.NET Mvc开发之查询数据
- ASP.NET MVC中将控制器分离到类库的实现
- asp.net实现在非MVC中使用Razor模板引擎的方法
- ASP.NET MVC中的AJAX应用
- 为ASP.NET MVC及WebApi添加路由优先级
- ASP.NET MVC中图表控件的使用方法
- 剖析ASP.NET MVC的DependencyResolver组件
- ASP.NET MVC的四种验证编程方式
- ASP.NET MVC @Helper辅助方法和@functons自定义函数的使用方法
- 仅30行代码实现Javascript中的MVC
- asp.net MVC利用ActionFilterAttribute过滤关键字的方法
- ASP.NET MVC使用ActionFilterAttribute实现权限限制的方法(附demo源码下载)
- ASP.NET MVC 3仿Server.Transfer效果的实现方法
- 如何在MVC应用程序中使用Jquery
- 利用ASP.NET MVC+EasyUI+SqlServer搭建企业开发框架