ASP.NET MVC3 系列教程 - URL友好化的重型武器[路由]
I:URL友好化的优势
在过去,我们开发ASP.NET应用程序的时候常常会使用URL的QueryString去传递参数给ASP.NET处理.
如:http://localhost:1029/Default.aspx?key_1=value_1&key_2=value_2&key_3=value_3
在使用此类URL格式去做门户网站时,非常不利于让搜索引擎收录页面.另外还包含.aspx结尾还会令搜索引擎爬虫烛觉得这个页面是动态页从而放弃收录或降低页面在搜索结果中的排名.
面对这个问题,我们为了讨好搜索引擎爬虫首先必须要做的是:
A:使QueryString彻底消失,让爬虫认为这是一个独立页面
B:将.aspx更改为可自定义的后缀名格式(伪静态)
C:正确设置robots.txt
实验例子:
注意:/Default/Value_1/Value_2/Value_3.html这个文件根本不存在于硬盘上~
我们做下对比
旧URL:
http://localhost:1029/Default.aspx?key_1=value_1&key_2=value_2&key_3=value_3
新URL:
http://localhost:2636/Default/Value_1/Value_2/Value_3.jsp
http://localhost:2636/Default/Value_1/Value_2/Value_3.html
与之前的URL作对比,新的URL更短并实现了自定义文件后缀格式!更利于爬虫进行检索收录工作
另外
以下的路径均属于1个页面:
/Default.aspx?key_1=something
/Default.aspx?key_1=anything
以下的路径将会分为多个页面(从访问者角度来看):
/Default/something.html
/Default/anything.html
像这类短URL还有助于用户记忆及反映站点结构,下面举个例子
比如在博客园里我的博客URL为http://www.cnblogs.com/highend/
而其他用户的URL则为http://www.cnblogs.com/UserName/
因为有了这个友好化URL,从而避免了出现尴尬的URL http://www.cnblogs.com/blog.aspx?userName=highend
接下来介绍在ASP.NET MVC当中友好化URL的实现!
II:在ASP.NET MVC3当中URL友好化的实现
在了解了URL友好化的优势以后,接下来将会为你介绍在ASP.NET MVC3中实现URL友好化的重型武器 - 路由.
小提示:路由并不是ASP.NET MVC独有!而是ASP.NET中的一个重要功能!MVC里的路由只不过是扩展了ASP.NET的路边由功能罢了!
1.ASP.NET MVC3路由注册的位置
当新建好一个MVC3项目后,可以在根目录下的Global.asax.cs文件内看到定义了一个继承System.Web.HttpApplication类的MvcApplication类,这个类里面就包含了MVC3的路由设置.具体请看下面贴出的MvcApplication部分代码
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults ); } protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); }
摘段MSDN的关于Application_Start的介绍
Application_Start 和 Application_End 方法是不表示 HttpApplication 事件的特殊方法。在应用程序域的生命周期期间,ASP.NET 仅调用这些方法一次,而不是对每个 HttpApplication 实例都调用一次。
在此MVC3应用程序是通过在Application_Start()方法里调用静态方法RegisterRoutes(RouteCollection routes)使ASP.NET有实例化MvcHandler的能力,而RegisterRoutes方法内的routes.MapRoute( … )是MVC3里对RouteCollection添加的扩展方法,位于System.Web.Mvc.RouteCollectionExtensions!
提示:ASP.NET路由是一个Module位于
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Config\web.config
<httpModules>
...
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" />
...
</httpModules>
2.ASP.NET MCV3路由的使用介绍
前面第1小节里,我们已经知道了ASP.NET MVC3对System.Web.Routing.RouteCollection类进行了扩展,下面我将列出扩展方法的重载列表.然后对其找出一个参数最多的进行详细介绍!
System.Web.Mvc.RouteCollectionExtensions类 - 扩展方法列表的详细地址:
第一个我要介绍的是IgnoreRoute(string url)方法~
他的功能是用于将参数内设置的url排除在路由处理程序之外,也就是:忽略给定可用路由列表和约束列表的指定 URL 路由。
我们引用上一节里面的一行代码
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
作用:使路由系统忽略处理ASP.NET的Web资源文件(WebResource.axd或ScriptResource.axd).
另外这里的{resource}与{*pathInfo}我还未能在官网上找到详细的介绍资料.~所以在这我也只好忽略不谈~接着关注MapRoute的功能.
MapRoute方法在RouteCollectionExtensions里有6个重载版本!在这里我挑了一个参数最多的重载版本来进行介绍
public static Route MapRoute(
this RouteCollection routes,
string name,
string url,
Object defaults,
Object constraints,
string[] namespaces
)
name:路由在路由列表里的唯一名字(两次MapRoute时name不能重复)
url:路由匹配的url格式
defaults:路由url {占位符} 的默认值
constraints:url的 {占位符} 的约束
namespaces:这个是用于设置路由搜索的控制器命名空间!
在此详细分别介绍一下url, defaults, constraints这三个重要参数
在上章节的代码里MapRoute里面使用到了MVC里提供的两个特殊占位符{controller}及{action}它们分别描述的内容具体如下:
对此当MapRoute设置为
routes.MapRoute( "Default" , //name "{controller}/{action}" , //url new { controller = "Home" , action = "Index" }, //defaults null , //constraints null //namespaces ); |
时,访问
http://localhost:2317/home/index
{controller} = home, {action} = index [注意,提交的url是不区分大小写的]
http://localhost:2317/Home/About
{controller} = home, {action} = about
http://localhost:2317/blog/home
{controller} = blog, {action} = home
http://localhost:2317/account/logon
{controller} = account, {action} = logon
在这里为你讲述一下defaults的作用.~
当你请求的Url属于
http://localhost:2317/
{controller} = null, {action} = null
http://localhost:2317/Home/
{controller} = home, {action} = null
http://localhost:2317/blog/
{controller} = blog, {action} = null
在此~defaults会自动利用你设置好的默认值去设置{controller}及{action}
new { controller = "Home", action = "Index" }, //defaults
所以~如果你请求的url属于这种错误格式http://localhost:2317//index时~defaults并不会帮你自动完成设置
因为设置要有一个先后次序!
OK.url参数就先介绍到这里,更多的用途我会放在下一篇(控制器 & 视图)文章当中进行讲解!
MapRoute目前剩下的1个参数constraints的功能是对先前定义的{占位符}进行添加一个正则约束比如:
routes.MapRoute( "constraints" , //name "{controller}/{action}" , //url null , //defaults new { controller = @"[a-z]{4,}" , //controller必须为英文字符,最少长度为4 action = @"[a-z]{4,}" //action必须为英文字符,最少长度为4 }, //constraints null //namespaces ); |
对于上面的MapRoute我们测试以下请求的URL的结果为:
/Home/index 通过
/Home/Seo 失败
/abc/Defgs 失败
如果你觉得正则匹配不符合你的要求那么你可以去实现System.Web.Routing.IRouteConstraint接口以满足你的要求!
在这里提及一下string[] namespaces参数.~
当在你的MVC3应用程序里建立了不是以Controllers结尾的控制器类命名空间时,就可以通过设置这个属性来让路由系统在url匹配时应该去找那些命名空间
routes.MapRoute("namespaces",
"{controller}/{action}",
null, null,
new string[] { "MvcApplication1.Custom" }
);
设置后此参数后路由系统就会去找
MvcApplication1.Controllers, MvcApplication1.Custom下带Controller结尾的继承于Controller的类了!
介绍一下建立有Area时路由的注册情况:
III:自定义文件后缀名的实例下载
下载源代码
示例内用到的是IIS Express如果你没有安装IIS Express的话需要更改.csproj文件内的
<UseIISExpress>true</UseIISExpress> 设置为相应的值
参考资料:MSDN, ASP.NET MVC 1.0高级编程
本文到此结束!