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是非常有用的一个功能,因为它可以让你提高搜索引擎阅读 ...
随机推荐
- .NET中 DAL+IDAL+Model+BLL+Web是什么意思
在.NET中 DAL+IDAL+Model+BLL+Web是什么意思 http://hi.baidu.com/hexiaojian/item/8d0c1a8e648546d75e0ec1e7 其实三层 ...
- poj3254:基础状压dp
第二个状压dp 做过的第一个也是放牛问题,两头牛不能相邻 这个题多了一个限制,就是有些位置不能放牛 于是先与处理一下每一行所有不能放牛的状态,处理的过程直接对每一个不能放牛的状态或以下 ac代码: # ...
- c语言typedef之数组运用
#include <stdio.h> #include <stdlib.h> typedef ];//int arr[4]取一个别名 arr b c就是int b[4] int ...
- hdu 4135 Co-prime(容斥)
Co-prime Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- C# 约瑟夫环算法
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- Hibernate试题解析
1.在Hibernate中,以下关于主键生成器说法错误的是(AC). A.increment可以用于类型为long.short或byte的主键(byte类型不可以) B.identity用于如SQL ...
- iOS学习之 plist文件的读写
在做iOS开发时,经经常使用到到plist文件, 那plist文件是什么呢? 它全名是:Property List,属性列表文件,它是一种用来存储串行化后的对象的文件.属性列表文件的扩展名为.pli ...
- maven pom.xml具体解释(整理)
pom作为项目对象模型. 通过xml表示maven项目,使用pom.xml来实现.主要描写叙述了项目:包含配置文件.开发人员须要遵循的规则,缺陷管理系统.组织和licenses,项目的url,项目的依 ...
- [CSS] :not Selector
The CSS :not() selector allows us to exclude a subset of elements matched by our selector. In this e ...
- ORACLE查看数据文件-控制文件-日志文件-表空间信息
1.查看当前数据库中的所有用户:select username from dba_users; 2.查看当前会话登录的用户:show user或select username from user_us ...
