ASP.NET MVC路由——没人告诉你的事
2018年1月24日路由是URL到处理该URL的逻辑的映射。在经典ASP.NET窗体网站中,路由并不那么令人感兴趣,因为经典ASP.NET窗体网站的URL直接映射到aspx文件,如https://gqqnbig.me/default.aspx就由default.aspx执行。
ASP.NET MVC的主要特性之一就是URL与具体的处理程序解耦了,处理程序称为Controller控制器,即MVC的C。不要以为URL不重要,用户用URL来探索站点结构。例如本文的URL是https://gqqnbig.me/2018/01/24/asp-net-mvc路由-没人告诉你的事/,用户期望删除后面部分,使用https://gqqnbig.me/2018/01/24/到达日度归档。另一方面,结构化的URL有助于搜索引擎优化。
既然路由是URL到处理控制器的映射,我们需要URL和控制器两者来定义路由。一个路由器对应一个路由,如default -> DefaultController,这种方式效率太低了,所以.NET Framework使用通配符和占位符的方法定义路由。
在Visual Studio中新建.NET Framework ASP.NET MVC应用程序,Global.asax.cs里有
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
其中RouteConfig.RegisterRoutes(RouteTable.Routes)
要求在应用程序启动时注册路由表,该方法的方法体为
对于(1)的作用,所有文章要么没解释,要么用同一句话解释[1][2][3]:不对.axd文件进行路由。但读者仍然不知道{resource}、“*”、斜杠的意思。这个就是URL模式。许多人,甚至是微软MVP[4],都不清楚它的具体用法。下面我们来研究它。
URL模式
路由需要定义URL模式,URL模式包含常量值、URI片段分隔符(斜杠)和占位符。
占位符由成对的大括号标记,如{resource}
、{id}
。两个占位符之间必须有常量值或斜杠,如{language}{country}/{action}
不是合法的URL模式,而{language}-{country}/{action}
是。占位符类似于变量,其名字是任意的,只要变量调用方调用正确的名字。下列URL模式具有完全相同的功能。
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{x}.axd/{*y}");
routes.IgnoreRoute("{hello}.axd/{*word}");
URI片段分隔符在Uri.Segments 属性有介绍,用于把URI(URL的超类)划分成不包括斜杠的片段。由定义可知,第一个URI片段永远为/
。
URL | URI片段 |
---|---|
http://www.contoso.com/Chapters/Chapter1/Sections/Section1.htm#page1?answer=NO |
|
https://www.google.com |
|
https://www.google.com/ |
|
此外,URI片段分隔符不能连续出现,否则将抛出异常。
在路由过程中,不是URL与URL模式直接匹配,而是URL片段与URL模式片段匹配。
占位符中的星号(*)将该占位符标识为变长占位符(Catch-all placeholder,全部捕捉占位符),变长意思是允许匹配多个或零个URI片段。使用{resource}.axd/{*pathInfo}
对下列URL进行匹配,占位符的捕获情况如下。
URL | URI片段 |
---|---|
https://gqqnbig.me/WebResource.axd?d=PhPk80h_UWEcbheb&t=632573240669964903 |
resource=WebResource pathInfo=空字符串 |
https://gqqnbig.me/ScriptResource.axd/underscore/1.0/ |
resource=”ScriptResource” pathInfo=”underscore/1.0/” |
https://gqqnbig.me/ScriptResource.axd/underscore/1.0 |
resource=”ScriptResource” pathInfo=”underscore/1.0/” |
https://gqqnbig.me/aspnet/ScriptResource.axd/underscore/1.0 | 不匹配 |
同params可变参数关键字一样,ASP.NET仅允许最后一个占位符为变长占位符。
代码1的(2)部分指定如何从URL映射到控制器。如果URL不足三段,则余下的占位符变量值取默认值。下标显示了多种情况下占位符的取值情况。
URL | 占位符取值 |
---|---|
https://gqqnbig.me/Home/About |
controller=”Home” action=”About” id=UrlParameter.Optional (取默认值) |
https://gqqnbig.me/Home |
controller=”Home” action=”Index” (取默认值) id=UrlParameter.Optional |
https://gqqnbig.me/ |
controller=”Home” (取默认值) action=”Index” (取默认值) id=UrlParameter.Optional |
https://gqqnbig.me/Czecho/Slovakia/Republic |
controller=”Czecho” action=”Slovakia” id=”Republic” |
https://gqqnbig.me/United/States/Of/America | 不匹配 |
这里不能随便命名占位符,因为{controller}
和{action}
是特殊占位符,分别表示控制器的类名和方法名。控制器方法如果想接受参数,参数名必须与其他的URL占位符相匹配。
参考资料
- Peter Johnson. MVC's IgnoreRoute syntax. . 2010-11-11 [2018-01-23].
- [CiteBook author=”Dino Esposito” title=”ASP.NET MVC 5编程实战” edition=”第三版” publisher=”清华大学出版社” isbn=”978-7-302-39480-8″]
参考资料
- huangenai. asp.net MVC 5 路由 Routing. . 2017-07-26 [2018-01-23].↑
- Alan_beijing. 【ASP.NET MVC系列】浅谈ASP.NET MVC 路由. . 2017-06-29 [2018-01-23].↑
- Amir Popovich. Can someone explain what routes.IgnoreRoute(“{resource}.axd/{*pathInfo}”); is need for?. . 2014-04-25 [2018-01-24].↑
- Edi Wang. ASP.NET MVC3和传统WebForm共存时,Chart控件无法显示的解决办法. . 2012-07-01 [2018-06-08].↑