我记录网站综合系统 -- 技术原理解析[4:我记录框架 路由系统]

news/2024/5/20 5:11:15/文章来源:https://blog.csdn.net/weixin_33769125/article/details/93313655

源代码位置:wojilu.Web.Mvc.Processors:RouteProcessor.cs

              :wojilu.Web.Mvc.Routes     :RouteTool.cs
客户端向服务器发送请求,主要是通过 url 链接的形式,是 url 告诉了服务器,应该返回什么样的信息。

路由(route)系统的目的,主要也就是将 url 解析成特定的数据,比如 url 中的 controller 是什么,action 是什么,id 又是什么,翻页是第几页等等。

如果还记得上一篇文章的话,wojilu系统通过IhttpHandler获得页面请求后,首先执行的就是RouteProcess,对的,第一步就是将请求的URL进行路由处理。

 Config ->

    wojilu.Web.Mvc.CoreHandler.ProcessRequest - >

          wojilu.Web.Mvc.CoreHandler.ProcessRequest: ProcessContext.Begin ->

               RouteProcess

 

 我们看看RouteProcess的主方法里面干了一些什么:
 
 1         public override void Process( ProcessContext context ) {
 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掉的。

wojilu mvc 中有一个 RouteTool,就是专门用来解析 url 的。解析完成的路由信息将放入ProcessContext传递到下一个Process中。

ProcessContext是一个巨大的内容容器,里面放着每一个请求的所有信息。在每一个Process后,都可能改变或者追加内容。
最后,判断一下,当前这个网站是否处于关闭状态。wojilu可以通过后台来控制网站是否对外公开。如果网站现在处于关闭状态的话,这个时候还需要检查一下是不是在请求网站后台登陆页面,如果是网站后台登陆页面的话,则进行后续操作;如果处于关闭状态,又非网站后台登陆页面的话,则将预设的关闭理由输出到用户请求页面,请求处理结束。 

 

 1         private void IsSiteClosed( MvcContext ctx ) {
 2 
 3             Boolean isAdmin = isSiteAdmin( ctx.route );
 4 
 5             if (!config.Instance.Site.IsClose || isAdmin != falsereturn;
 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 );

通过 Recognize 方法,就得到了结果,也就是一个 Route 对象,各属性的值是:
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)(字符串)

 

wojilu mvc 在解析并获取到这些值之后,会传递给 MvcContext,然后框架根据 controller 和 action 的字符串,创建相应的 controller 对象。这些过程,都是框架自动处理的。所以,开发者一般不需要用到 ctx.route.controller 等的字符串的值。

下面举个例子,比如 Article/2/Edit.aspx 这个 url ,在被解析之后,其实对应着 ArticleController 的 Edit(int id) 方法;
而 Article/2.aspx 这个 url,在被解析之后,则对应着  ArticleController 的 Show(int id) 方法,默认 Show 方法不在 url 中显示。

基本上,开发者不用操心链接的生成和路由的解析这个事情。只有在你需要自定义路由解析规则的时候,才需要理解下面的内容。

一、常规路由

路由的规则是由配置文件 /framework/config/route.config 定义的:

我 们看第三行,这条规则把 url 分成两部分,controller和id部分,如果一个 url 是由两部分组成,并且第二部分符合后面的要求(requirements)是整数,那么这个 url 的第一部分就是 controller,第二部分就是 id,比如 Article/3.aspx 的控制器就是 ArticleController(Controller后缀会自动补上),ID就是 3。

下面几行路由规则的解析原理依次类推。

那 么,第一条路由(第一行那个)是什么意思?它表示,如果请求的 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”等在内的多 用户系统。
三、查询参数
我们先看一下传统的方式。在传统的web开发中,一个页面向另外一个页面传递参数,是通过queryString的方式进行的,也就是在网址后面附上一个问号和几个参数列表,比如:
/product.aspx?factory=联想&category=pc
然后在服务端通过 Request.QueryString( "factory" ) 和 Request.QueryString( "category" ) 依次获得 factory 和 category 的值。
在wojilu框架中,这种方式仍然支持。但对 Request.QueryString 进行了简化,用 ctx.Get("") 代替,效果是一样的。也就是说 ctx.Get("factory") 和 Request.QueryString( "factory" ) 的值完全相同。
但是这种带问号?的参数传递方式有一些缺点,主要是SEO不够友好。传统的解决方法是使用url重写(rewrite)。大概思路这样:
1)设计一个对SEO友好的网址,比如 product/联想/pc.aspx
2)设计一个重写的正则匹配表,此处省略;
3)添加代码,在客户端请求到达服务器之后、正式解析之前,将 product/联想/pc.aspx 这样的网址解析成传统的 /product.aspx?factory=联想&category=pc 形式。
在 wojilu 框架中,不用重写(rewrite)技术,直接使用自定义路由功能,即可达到类似效果。
1)在路由中增加如下规则项:
search/{query};default:{controller=_.Main,action=Search}
product/{factory}/{category};default:{controller=_.Product,action=List}
book/{author};default:{controller=_.Book,action=List}
2)如果是 product/苹果/电脑.aspx 类似的网址,服务端可以通过 ctx.route.getItem( "factory" ) 来获得。以下是测试代码,供参考:
result = RouteTool.RecognizePath( "search/新闻" );
Assert.AreEqual( result.controller, "Main" );
Assert.AreEqual( result.action, "Search" );
Assert.AreEqual( result.query, "新闻" );

result = RouteTool.RecognizePath( "product/苹果/电脑" );
Assert.AreEqual( result.controller, "Product" );
Assert.AreEqual( result.action, "List" );
Assert.AreEqual( result.getItem( "factory" ), "苹果" );
Assert.AreEqual( result.getItem( "category" ), "电脑" );

result = RouteTool.RecognizePath( "book/金庸" );
Assert.AreEqual( result.controller, "Book" );
Assert.AreEqual( result.action, "List" );
Assert.AreEqual( result.getItem( "author" ), "金庸" );
3)如何生成 product/苹果/电脑.aspx   类似的链接?默认的 Link.To 或者 controller 自带的to方法,并不支持字符串参数,所以你需要自己写一个帮助方法来生成链接,具体方法就是拼接字符串,比如:
public String getProductLink( String factory, String category ) {
return "/product/" + factory + "/" + category + MvcConfig.Instance.UrlExt;
}
【常见问题】
比如自定义路由——
article/{typeid}/{id};default:{controller=Article,action=List}
却发生错误——
url=http://localhost:53091/article/12/1 
ex.Message=控制器不存在: article.Article 

请将自定义路由的controller前面加上“下划线和点号”,如下
article/{typeid}/{id};default:{controller=_.Article,action=List}
“下划线和点号”表示前面没有namespace,否则article会被加上。
补充:关于双向路由

熟悉 rails 的用户,会关心双向路由的问题。我的答案是,目前 wojilu mvc 不支持双向路由。原因是 wojilu mvc 要支持namespace,要支持不带查询形式(即?page=99这种url)的翻页链接,所以目前没有使用双向路由。
但使用上面的自定义路由功能,一样能得到类似的效果。另 外,wojilu mvc 在实践中发现,虽然不支持双向路由,但一样能工作得非常良好,“我记录网站综合系统”就是一个活生生的项目例子。还有,因为 wojilu mvc 支持 namespace,所以你完全可以通过controller灵活的目录划分方式,来获得具有 RESTfull 风格的、语义清晰的url。


官网的路由相关文章:http://www.wojilu.com/Common/Page/74

如果有关于路由的任何问题,请在以上页面留言。管理者会热情回复您的疑问。

我记录网址 www.wojilu.com

欢迎大家加入我记录开发团队

 

转载于:https://www.cnblogs.com/TextEditor/archive/2011/06/14/2079581.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_749089.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用access作为.net网站的数据库,在windows2003上配置出现,出错不能访问。

最近在将做好的毕业设计挂在服务器上浏览,总是出现错误,无法访问。网上查了很多方法,感觉都没有很好的答案,发表一下,和大家一起共享一下。希望大家多多提建议。 我的数据库是access2007,首先,由…

asp.net mvc 2.0+Silverlight播放器开发的TeamVideo视频播放网站--系列2

这几天抽空写第二部分。很高兴今天能够和大家分享下。我这是个asp.net mvc的新手。。。希望各位提出宝贵的意见。 你可以在这里查看第一部分的内容。http://www.cnblogs.com/n-pei/archive/2010/08/30/1812981.html 按照之前计划,这一部分的内容如下: 1.…

锦绣蓝图:怎样规划令人流连忘返的网站(第2版)(全彩印刷,信息架构之父R. S. Wurman隆重推荐)...

锦绣蓝图:怎样规划令人流连忘返的网站(第2版)(全彩印刷,信息架构之父R. S. Wurman隆重推荐)【原 书 名】 Information Architecture: Blueprints for the Web (2nd Edition) 【原出版社】 New Riders Press 【作  者】(美)Christina Wodt…

网站(bs系统)怎样实现即时消息思路总结

为什么80%的码农都做不了架构师?>>> 1.ajax刷新 2.flashsocket(推荐,网页游戏多用这个) 3.DWR用来做即时通讯很方便 4.Comet 有时也称反向 Ajax 或服务器端推技术(server-side push),这个东西其实就是长连接&#xff…

手机php网站不显示图片,javascript,_手机页面用innerHTML拼接的图片不显示,javascript - phpStudy...

手机页面用innerHTML拼接的图片不显示测试代码input,button{height:35px;}add function addEmotion(t){alert(t);}var addfunction(){var prefixhttp://192.168.1.100:88/emotion/images/;var emotion[hi,yes,good];var html[];for(var i0;ihtml.push("");}document.…

计算机的电子邮件地址怎么看,电脑使用小技巧:如何找出网站上隐藏的电子邮件地址?...

当访问有些网站时,有时我们需要与网站进行联系,可是点击网站上的“联系我们”时,并没有出现详细的联系信息,比如:地址,邮件,电话等,电脑反而弹出outlook邮件客户端程序。如果我们平时…

dwz框架在网站群项目中的应用(3)—html拓展之控件组件篇

每个页面中由不同的控件和组件提供不同的功能,在“dwz框架”下应用框架的规则只要写简单的html代码就可以写出实用的控件或组件,在项目中用的比较多的有:文本框、日历控件、combox组件、分页组件,下面将继续以项目中的实例介绍这些…

大型网站技术架构(六)网站的伸缩性架构

2019独角兽企业重金招聘Python工程师标准>>> 网站系统的伸缩性架构最重要的技术手段就是使用服务器集群功能,通过不断地向集群中添加服务器来增强整个集群的处理能力。“伸”即网站的规模和服务器的规模总是在不断扩大。 1、网站架构的伸缩性设计 网站的…

大型网站技术架构(一)大型网站架构演化

2019独角兽企业重金招聘Python工程师标准>>> 看完了有一本书,就应该有所收获,有所总结,最近把《大型网站技术架构》一书给看完了,给人的印象实在深刻,再加上之前也搞过书本上讲的反向代理和负载均衡以及ses…

Smint – 用于单页网站制作的 jQuery 导航菜单插件

Smint 是一款用于实现单页风格网站的 jQuery 导航插件,包含两部分:固定在页面顶部的精美导航条和能够在你点击的时候自动滚动到对应内容的菜单按钮。Smint 使用非常简单,只有一个参数用于设置页面滚动的速度,默认是 500 毫秒&…

大型网站架构演变和知识体系

之前也有一些介绍大型网站架构演变的文章,例如LiveJournal的、ebay的,都是非常值得参考的,不过感觉他们讲的更多的是每次演变的结果,而没有很详细的讲为什么需要做这样的演变,再加上近来感觉有不少同学都很难明白为什么…

转一篇架构师间的问答------如何对应大数据量网站的考验

提问嘉宾: 林昊,网名BlueDavy,China OSGi User Group Director,淘宝网平台架构部架构师,个人的研究方向主要为Java模块化、动态化系统的构建以及高性能的大型分布式Java系统的构建。曾编写《OSGi实战》和《OSGi进阶》…

《大型网站技术架构》读书笔记 - 网站的技术升级路线

《大型网站技术架构》读书笔记 - 网站的技术升级路线 本文描述网站从小到大演变过程中的技术升级路线; 1.初始架构 一台服务器,应用、DB、文件都在一块,使用经典的LAMP模式构建整个站点; 优点很明显,开发部署都简单&am…

历史最全Transformer注意力机制综述论文、代码及网站资源整理分享

Google于2017年6月在arxiv上发布了一篇非常经典的文章:Attention is all you need,提出了解决sequence to sequence问题的transformer模型,该文章使用全Attention的结构代替了LSTM,抛弃了之前传统的encoder-decoder模型必须结合CN…

网站架构的伸缩性设计

网站开发初期,我们习惯性把所有代码都写到一个项目中。前台、后台、缓存、数据库、静态资源... 等等。网站系统物理分离慢慢的系统会原来越大,很显然需要面对大量用户的高并发访问和存储海量数据。很多用户的请求,不可能在一台服务器上完成。…

11月钓鱼网站:.COM域名超56% 新网数码占比37%

IDC评述网(idcps.com)12月15日报道:近日,中国反钓鱼网站联盟发布了《2014年11月钓鱼网站处理简报》。据报告显示,11月份,联盟共处理钓鱼网站4820个,较上月有所增加;截至2014年11月份…

采用SharePoint Designer将JavaScript而他们的网站页面集成的定义

采用SharePoint Designer将JavaScript而他们的网站页面集成的定义 像JavaScript这种动态脚本语言可以给你的页面震撼效果。为了加盟JavaScript要定义自己的网站页面。面步骤:1. 打开SharePoint Designer 2010. 点击左側站点页面。2. 新建Web Part页面,重…

如何用代码设置控制自己网站的网页在360浏览器打开时强制优先使用极速模式,而非兼容模式...

在head标签中添加一行代码&#xff1a; <html><head><meta name"renderer" content"webkit|ie-comp|ie-stand" /></head><body></body> </html> content的取值为webkit,ie-comp,ie-stand之一&#xff0c;区分大…

IIS10 部署网站报【HTTP 错误 500.19 - Internal Server Error】的解决办法

今天迁移web服务突然遇到一个Error问题&#xff0c;但原有的web发布文件是可以正常部署 IIS10 上面运行的&#xff0c;这是啥情况呢&#xff1f;顺便把解决该问题的全过程整理出来&#xff0c;分享给更多遇到类似情况的小伙伴。 由于本地电脑环境迁移&#xff0c;重新换了一个…

IIS 部署网站对 OPTIONS 请求直接返回 40x 的处理

什么是 OPTIONS 请求 OPTIONS 请求为 ** 发送非简单跨域请求前的预检请求** &#xff0c;若该请求未正常返回&#xff0c;浏览器会阻止后续的请求发送。 一般情况下&#xff0c;有三种方式会导致浏览器发起预检请求&#xff1a; 请求的方法不是 GET/HEAD/POST&#xff1b; PO…