我记录网站综合系统 -- 技术原理解析[4:我记录框架 路由系统]
源代码位置:wojilu.Web.Mvc.Processors:RouteProcessor.cs
:wojilu.Web.Mvc.Routes :RouteTool.cs路由(route)系统的目的,主要也就是将 url 解析成特定的数据,比如 url 中的 controller 是什么,action 是什么,id 又是什么,翻页是第几页等等。
如果还记得上一篇文章的话,wojilu系统通过IhttpHandler获得页面请求后,首先执行的就是RouteProcess,对的,第一步就是将请求的URL进行路由处理。
Config ->
wojilu.Web.Mvc.CoreHandler.ProcessRequest - >
wojilu.Web.Mvc.CoreHandler.ProcessRequest: ProcessContext.Begin ->
RouteProcess
2
3 MvcEventPublisher.Instance.BeginParseRoute( context.ctx );
4 if (context.ctx.utils.isSkipCurrentProcessor()) return;
5
6 Route r = RouteTool.Recognize( context.ctx );
7 context.ctx.utils.setRoute( r );
8
9 IsSiteClosed( context.ctx );
10 }
首先,通过EventPublisher向系统进行广播,我们现在要开始一个路由解析过程了,这个时候如果有其他监听者的话,可以进行一些预处理工作。接下来看看这个过程是不是可以Skip掉,在wojilu里面,可以在结束当前Process的时候设定下一个Process是否可以Skip(跳过)。当然,这里理由是第一个Process,不会Skip掉的。
2
3 Boolean isAdmin = isSiteAdmin( ctx.route );
4
5 if (!config.Instance.Site.IsClose || isAdmin != false) return;
6 ctx.web.ResponseWrite( config.Instance.Site.CloseReason );
7 ctx.web.ResponseEnd();
8 }
9
10 private Boolean isSiteAdmin( Route route ) {
11 String ns = route.ns;
12 if (strUtil.IsNullOrEmpty( ns )) return false;
13 if (ns.StartsWith( "Admin." ) || ns.Equals( "Admin" )) return true;
14 return false;
15 }
Route r = RouteTool.Recognize( context.ctx );
ctx.route.id | 当前ID(整数) |
ctx.route.controller | 当前控制器(字符串) |
ctx.route.action | 当前控制器的方法(字符串) |
ctx.route.owner | 被访问对象(字符串) |
ctx.route.ownerType | 被访问对象的类型(site/group/user等)(字符串) |
ctx.route.appId | 当前应用程序的appId(有时候可以为0)(整数) |
ctx.route.page | 当前页面(在翻页的时候出现)(整数) |
ctx.route.query | 当前url中的查询字符串(QueryString)(字符串) |
下面举个例子,比如 Article/2/Edit.aspx 这个 url ,在被解析之后,其实对应着 ArticleController 的 Edit(int id) 方法;
而 Article/2.aspx 这个 url,在被解析之后,则对应着 ArticleController 的 Show(int id) 方法,默认 Show 方法不在 url 中显示。
基本上,开发者不用操心链接的生成和路由的解析这个事情。只有在你需要自定义路由解析规则的时候,才需要理解下面的内容。
一、常规路由
路由的规则是由配置文件 /framework/config/route.config 定义的:

下面几行路由规则的解析原理依次类推。
那 么,第一条路由(第一行那个)是什么意思?它表示,如果请求的 url 是 default.aspx ,则默认(default)使用 MainController;但它没有指定默认的action。在没有 id 的情况下,默认的 action 是 Index;如果有 id ,则默认的 action 是 Show。
二、自定义路由
有些网址比较长,比如 www.wojilu.com 的论坛网址实际是: http://www.wojilu.com/Forum1/Forum/Index 在域名后面的路径为 /Forum1/Forum/Index ,不容易记忆,这时候,自定义路由就派上了用场。请在 route.config 中增加一行:
bbs;default:{ownertype=site,owner=site}
你 可以和原先 route.config 中的第一行比较一下,其实是差不多的。它的意思是,bbs.aspx 将被解析到 site 对象的默认 controller 的默认 action 上,但是奇怪的是,没有定义默认的 controller?这是“我记录网站综合系统”在路由基础上,额外增加的一个功能,就是默认controller根据数据库中的菜单设置决定。这部分 你可以进一步参考“我记录网站综合系统”。
我们甚至可以将首页指向特定的用户,比如某用户名的友好url是 zhangsan,那么如果你第一行修改成这样:
default;default:{owner=zhangsan,ownertype=user}
那么,用户访问网站首页,就会直接看到 zhangsna 这个用户的空间首页。顺便说一下,这意味着你完全可以把 “我记录网站综合系统” 这个多用户系统当做个人独立博客使用, 比起那些单用户博客系统来说,要方便、强大得很多。这就像你把 windows 2003 当 windows xp 用,把wondows 2008当 windows 7 用一个道理。另外,这样使用还有个好处,就是一旦你的独立博客有了一定知名度,你完全可以简单修改一下路由,就把它转换成支持“论坛/SNS”等在内的多 用户系统。
1)设计一个对SEO友好的网址,比如 product/联想/pc.aspx
2)设计一个重写的正则匹配表,此处省略;
3)添加代码,在客户端请求到达服务器之后、正式解析之前,将 product/联想/pc.aspx 这样的网址解析成传统的 /product.aspx?factory=联想&category=pc 形式。
public String getProductLink( String factory, String category ) {
return "/product/" + factory + "/" + category + MvcConfig.Instance.UrlExt;
熟悉 rails 的用户,会关心双向路由的问题。我的答案是,目前 wojilu mvc 不支持双向路由。原因是 wojilu mvc 要支持namespace,要支持不带查询形式(即?page=99这种url)的翻页链接,所以目前没有使用双向路由。
官网的路由相关文章:http://www.wojilu.com/Common/Page/74
如果有关于路由的任何问题,请在以上页面留言。管理者会热情回复您的疑问。
我记录网址 www.wojilu.com
欢迎大家加入我记录开发团队
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架