ASP.NET MVC URL重写与优化(进阶篇)-继承RouteBase
原文地址:http://www.51csharp.com/MVC/882.html
|
引言-- 在初级篇中,我们介绍了如何利用基于ASP.NET MVC的Web程序中的Global文件来简单的重写路由。也介绍了它本身的局限性-依赖于路由信息中的键值对: 如果键值对中没有的值,我们无法将其利用凑出我们想要的URL表达式。 初级篇传送门:使用Global路由表定制URL
在进阶篇中,我们将介绍ASP.NET 路由相关类的基类-抽象类RouteBase,并演示如何通过继承它,让URL重写和优化变成Free Style。 一,老板的需求 假设我们是手机销售网站的一名程序猿(承接初级篇),经过第一次的URL重写之后,我们的手机分类页面的URL的改变: http://www.xxx.com/category/showcategory?categoryid=0001&view=list&orderby=price&page=1 现在老板又提出了新的需求,URL的语义化,从而更好的反应网站的结构: http://www.xxx.com/ca-categoryname 比如Nokia是一个分类,那么对应URL为 /ca-nokia,如果是iPhone分类,URL则对应 /ca-iphone。ca前缀的意思是分类category。 对于这个需求简单的配置Global文件是无法做到的。首先我们来介绍一下ASP.NET 路由的所有类的基类RouteBase。 二,RouteBase类简介与运行机制
1. RouteBase类位于System.Web.Routing命名空间,结构如下: public abstract class RouteBase
看完以上定义,可能大家会晕忽忽。我们来弄一个简单的例子说明这几个方法是如何运作的。 首先我们新建一个类库JohnConnor.Routing,并且继承抽象类RouteBase: ![]() using System; ![]() 这样CategoryUrlProvider类就包含了用来处理路由映射的方法。 首先我们需要在Web程序中添加JohnConnor.Routing类库的引用,然后我们把CategoryUrlProvider类注册到Global文件的路由表中。 public static void RegisterRoutes(RouteCollection routes) 这里相当于添加了一条新的路由规则。重新生成一下Web程序在CategoryUrlProvider中打好断点,F5启动。 2. GetRouteData()方法 这时候相当与你在浏览器输入了http//localhost:1234/<假设本地端口号是1234>,此时程序需要判断这个URL匹配的是哪个路由值。 自上而下的匹配,首先会尝试匹配我们新增的分类路由规则,此时会命中GetRouteData()方法中的断点。 因为我们返回了null,意味着该请求与我们新增的分类路由规则不匹配,那程序将在路由表中继续自上而下的进行匹配。 直到在主页这一条规则中与其URL表达式匹配,获取了对应的路由值-调用HomeController.Index()方法。 如果你把GetRouteData()方法修改一下: ![]() public override RouteData GetRouteData(System.Web.HttpContextBase httpContext) ![]() 你就会发现,无论你在http//localhost:1234/后面输入任何相对URL,都会被定向到HomeController.Index()方法。 因为返回的是路由值而不是null,表示已经找到匹配项,就不会再往下匹配了。<这条规则覆盖了后面所有的规则> 当然,请不要这样写。。。 由此可以推断出GetRouteData()方法在路由映射中担任的角色:处理请求中的URL,返回相应的路由值,不处理或不匹配则返回null。 3. VirtualPathData()方法 如果你在Razor页面有这样一段通过指定路由值来获取URL的代码 <a href="@Url.Action("Index", "Home")">首页</a>
当视图引擎渲染页面到这句代码时,HomeController.Index()方法会被解析为一个RouteValueDictionary类型的不分大小写的键值对<假设键值对对象为values>: values["controller"]="Home"; 这个键值对表示了一个路由值。 同样是在路由表中自上而下的匹配这个路由值,尝试第一条分类规则时,就会命中VirtualPathData()方法中的断点。 我们返回一个null,表示不匹配,则程序进行下一个规则的匹配。 直到找到主页规则的路由值与之匹配时,构造出相应的相对URL"",并返回该URL。 显示为: <a href="http://localhost:1234/">首页</a> 如果我们也改写一下VirtualPathData()方法:
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) 结果是你通过上述方法构造的URL不论请求来自哪里,全部都会显示成http://localhost:1234/This-is-a-Test-URL 因为我们返回的是一个相对路径,而不是null,表示已经找到匹配项,则匹配不会往下继续。<同上这条规则覆盖了后面所有的规则> 再一次提示,请不要这样写。。。 由此可看出,VirtualPathData()在路由映射中的活:处理请求与路由键值对,生成相应URL,不处理或不匹配则返回null。 4.方法重写的规则 在上文中,我一再的用红色字体提示,请不要这样写。因为每一个URL的重写类,建议仅仅处理尽可能少的路由映射。 比如CategoryUrlProvider仅处理CategoryController.Show(string categoeyid)这一个Action方法的映射。凡是不是这个方法相关的映射,都返回null。 继续去匹配别的规则。 三,开始动手把~ 为了最快的说明问题,我们简化了网站的内容。以下内容有助于理解后面的程序,如果时间充裕,还是自己构建一个网站来尝试以下。 首先我们在JohnConnor.Routing类库中创建Category.cs来保存分类模型,并把所有的分类显示的保存在List<Category>中, ![]() using System; ![]() 假设我们网站的CategoryController是这样的。 ![]() using System; ![]() 首先我们建议,VirtualPathData()和GetRouteData()方法是成双成对出现的。一旦你制定了一条路由规则,比如分类规则/ca-categoryname,那么:
!!!两者相辅相成的完成了路由值和URL的相互映射,漏掉一个,就不能构成一个完成的路由规则。直接结果是出现404或生成URL地址错误。 GetRouteData()的代码: ![]() public override RouteData GetRouteData(System.Web.HttpContextBase httpContext) ![]() VirtualPathData()的代码 ![]() public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) ![]() 至此,我们就把这条路由规则的映射处理完整了。如果你掌握了上述技术,任何的URL重写和优化需求,我相信你都能Hold住。 如果我们的主页页面是这样<Razor视图引擎>: ![]() @model List<JohnConnor.Models.Category> ![]() 三个分类连接会得到这样的结果 <a href="/ca-nokia">Nokia</a> 点击每一个连接都会先进入我们的处理程序,生成相应的路由值-调用CategoryController.Showcategory(string id)方法根据id显示相应的分类页面。 ------------------------------------------------------进阶篇完---------------------------------------------------
这一篇我花费了不少时间去构思如何用简单的例子讲述继承RouteBase来进行URL重写与优化。 希望能帮助到有用的人。 |
ASP.NET MVC URL重写与优化(进阶篇)-继承RouteBase的更多相关文章
- ASP.NET MVC URL重写与优化(进阶篇)-继承RouteBase玩转URL
http://www.cnblogs.com/John-Connor/archive/2012/05/03/2478821.html 引言-- 在初级篇中,我们介绍了如何利用基于ASP.NET MVC ...
- [转载]ASP.NET MVC URL重写与优化(进阶篇)-继承RouteBase玩转URL
引言-- 在初级篇中,我们介绍了如何利用基于ASP.NET MVC的Web程序中的Global文件来简单的重写路由.也介绍了它本身的局限性-依赖于路由信息中的键值对: 如果键值对中没有的值,我们无法将 ...
- [转]ASP.NET MVC URL重写与优化(进阶篇)-继承RouteBase玩转URL
本文转自:http://www.cnblogs.com/John-Connor/archive/2012/05/03/2478821.html 引言-- 在初级篇中,我们介绍了如何利用基于ASP.NE ...
- ASP.NET MVC URL重写与优化(初级篇)-使用Global路由表定制URL
ASP.NET MVC URL重写与优化(初级篇)-使用Global路由表定制URL 引言--- 在现今搜索引擎制霸天下的时代,我们不得不做一些东西来讨好爬虫,进而提示网站的排名来博得一个看得过去的流 ...
- ASP.NET MVC URL重写与优化(1)-使用Global路由表定制URL
ASP.NET MVC URL重写与优化(1)-使用Global路由表定制URL 引言--- 在现今搜索引擎制霸天下的时代,我们不得不做一些东西来讨好爬虫,进而提示网站的排名来博得一个看得过去的流量. ...
- ASP.net的url重写
http://blog.csdn.net/windok2004/article/details/2432691 1. 有关于URL的重写,本文也只是拿来主意.相继有MS的组件“URLRewriter” ...
- asp.net 页面url重写
不更改情况下,页面路径为index.aspx?id=1,现在输入页面路径index/1时,也能访问到页面,这一过程叫做url重写 ①:在一个类里制定路径重写规则,以下为自定义UrlRewriterFi ...
- (转)ASP.net的url重写
1. 有关于URL的重写,本文也只是拿来主意.相继有MS的组件“URLRewriter”和在Global.asax里的“Application_BeginRequest()”编码方式,以及IIS里的I ...
- Asp.net实现URL重写
原文:Asp.net实现URL重写 [概述] URL重写就是首先获得一个进入的URL请求然后把它重新写成网站可以处理的另一个URL的过程.重写URL是非常有用的一个功能,因为它可以让你提高搜索引擎阅读 ...
随机推荐
- 充分发挥 JavaScript 语言的优势
尽管我在生产环境中使用 JavaScript 长达 8 年之久了,但是,直到最近 2 年,我才开始学习如何正确地编写 JavaScript 代码,根据我对人们的理解,很多开发者都有类似经历.我们有相当 ...
- OC 图片圆角实现
self.imageTouX.layer.masksToBounds=YES; self.imageTouX.layer.cornerRadius=/2.0f; //设置为图片宽度的一半出来为圆形 s ...
- ubuntu14.04 cocos2d-x-3.6 glfw编译出错解决方案
lib/libcocos2d.a(CCGLViewImpl-desktop.cpp.o): In function `cocos2d::GLViewImpl::GLViewImpl()': /home ...
- js笔记01
js编写页面特效动态脚本类型的语言变量:存储数据(日常生活中的东西,比如电视,手机,电脑,出生年份...)语法: var obj=value; obj不能为数字开头,且区分大小写 value对应数据类 ...
- jQuery鼠标悬停图片放大显示
jQuery鼠标悬浮放于图片上之后图片放大显示的效果,即鼠标移到图片上图片突出显示,鼠标移开后恢复原来的模样,你可以在图片滚动效果中加上本特效,相信会更炫一些. <!DOCTYPE html P ...
- css如何使背景图片水平居中
CSS中定位背景图片的属性是:background-position,用法background-position 属性设置背景图像的起始位置. 你要水平居中可以: div{background-pos ...
- gzcompress, gzencode, gzdeflate三个压缩函数的对比
PHP的自带的函数中,有三个压缩相关的函数:gzcompress.gzencode.gzdeflate,下面我们通过一段程序,来比较一下这三个函数的压缩比.代码:$string = "8ae ...
- 未知宽高div水平垂直居中3种方法
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> </head&g ...
- HTML精确定位:scrollLeft,scrollWidth,clientWidth,offsetWidth之全然具体解释
HTML:scrollLeft,scrollWidth,clientWidth,offsetWidth究竟指的哪到哪的距离之全然具体解释scrollHeight: 获取对象的滚动高度. scrol ...
- 修改EF的默认约定模型的方式
EF默认使用约定的模型,但是有时类不遵从约定,我们需要能够执行进一步的配置.对此有两种方法:数据注释和Fluent API 注释 class User { [Key] public int Key{ ...
