004_URL 路由 - 对磁盘文件的请求进行路由
MVC应用的请求除了针对控制器和动作的,还有需要对内容进行服务的方法,如对图像、静态HTML文件、JavaScript库等等。请看下面演示示例:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Static HTML Content</title> </head> <body> This is the static html file(~/content/StaticContent.html) </body> </html>
默认情况下,路由系统在评估应用程序的路由之前,会考察一个URL是否匹配一个磁盘文件,也就是说不必为对静态文件请求的URL添加路由。如果将RouteCollection的RouteExistingFiles属性设置为true,则可以实现在检查磁盘文件之前就进行路由评估。如:routes.RouteExistingFiles = true;(注:一般需将这句话放在紧靠RegisterRoutes方法的顶部,当然也可以放在其他位置。)
为磁盘文件定义路由
下面,在RouteExistingFiles属性设置为true后,便可以定义对磁盘文件进行响应的URL相匹配的路由,如(下面加粗部分):
public static void RegisterRoutes(RouteCollection routes) { // 下面这句话的作用是启用文件检查前的路由评估 routes.RouteExistingFiles = true; routes.MapRoute("DiskFile", "Content/StaticContent.html", new { controller = "Customer", action = "List" }); routes.MapRoute("ChromeRoute", "{*catchall}", new { controller = "Home", action = "Index" }, new { customConstraint = new UserAgentConstratint("Chrome") }, new string[] { "UrlsAndRoutes.AdditionalControllers" }); routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }, new string[] { "UrlsAndRoutes.Controllers" }); }
如果项对磁盘文件请求进行路由,需要慎重考虑,这不仅仅是因为URL模式会像其他情况一样,对这些种类的URL进行匹配,还可能得到一些奇怪的结果,并导致性能下降。所以,非不得已最好不要启用这种做法。
绕过路由系统
上面设置的RouteExistingFiles属性使得路由系统更具有包容性,但可以通过设置IgnoreRoute方法可以让路由系统少一些包容性。如:
public static void RegisterRoutes(RouteCollection routes) { // 下面这句话的作用是启用文件检查前的路由评估 routes.RouteExistingFiles = true; // 使用 IgnoreRoute 方法 routes.IgnoreRoute("Content/{filename}.html"); routes.MapRoute("DiskFile", "Content/StaticContent.html", new { controller = "Customer", action = "List" }); routes.MapRoute("ChromeRoute", "{*catchall}", new { controller = "Home", action = "Index" }, new { customConstraint = new UserAgentConstratint("Chrome") }, new string[] { "UrlsAndRoutes.AdditionalControllers" }); routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }, new string[] { "UrlsAndRoutes.Controllers" }); }
可以用{filename}这样的片段变量来匹配一组URL。此时,该URL模式将匹配任何两片段URL,其第一片段是content,第二片段内容具有.html扩展名。
IgnoreRoute方法在RouteCollection中创建了一个条目,其路由处理器是StopRoutingHandler类的一个实例,而不是MvcRouteHandler。如果传递给IgnoreRoute方法的URL模式得到匹配,那么将不在评估后续的路由,就像有一条唱歌路由已得到匹配时一样。(IgnoreRoute方法的作用是:忽略给定可用路由列表的指定 URL 路由)