当前位置: 首页 > 文章教程  > 计算机与互联网 > 网络编程

10.6URL路由

8/31/2020 8:52:25 PM 人评论

10.6URL路由

10.6 URL路由

学习目标

了解URL路由的概念及作用。

本节,会结合10.4节的例子,深入分析ASP.NET MVC应用程序中URL路由的概念以及URL路由在ASP.NET MVC 4 Web程序中的作用。

10.6.1 一个URL并不等同于一个页面

当创建一个传统的ASP.NET Web窗体应用程序,或者是一个动态服务器页面(ASP)应用程序时,在URL与页面之间存在一一对应的关系。如果请求服务器上的一个名为abc.aspx的页面,那么服务器对应磁盘上就会有一个abc.aspx页面。如果abc.aspx文件在服务器上不存在,开发人员将会获得“404-页面不存在错误”。

当创建一个ASP.NET MVC应用程序时则大不相同,输入到浏览器地址栏的URL与应用程序中的文件之间并没有一个对应关系。在一个ASP.NET MVC应用程序中,一个URL与一个控制器的动作(Action)相对应,而不是磁盘上的具体页面。

例如,在MVC 4 Web程序中访问“/Home/Index”地址,就是访问Home Controllers这个控制器类的Index方法,方法可能直接在客户端浏览器中输出结果,也可能会调用控制器对应的视图来呈现在客户端,具体就看HomeControllers控制器中的方法是如何定义的。

10.6.2 理解URL路由

URL路由(URL Routing)使用一张路由表处理到来的请求。这个路由表在MVC 4 Web应用程序首次启动时创建在RouteConfig.cs这个文件中。

而在系统全局文件Global.asax中通过在Application_Start()事件中的"RouteConfig.RegisterRoutes(RouteTable.Routes);"调用,在Web应用程序启动时来创建路由。系统默认创建的RouteConfig.cs源代码如下。

public class RouteConfig
  {
    public static void RegisterRoutes(RouteCollection routes)
    {
       routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

       routes.MapRoute(
          name: "Default",
          url: "{controller}/{action}/{id}",
          defaults: new{controller="Home",action = "Index",id =
          UrlParameter.Optional }
       );
    }
  }

很显然,默认的路由表只含有一个路由。这个默认的路由将所有到来的请求分为了3个分段(一个URL分段是正斜杠之间的任何内容)。第一个分段映射到了控制器名称,第二个分段映射到了动作名称,最后一个分段映射到了传递给动作的名为Id的参数。

例如,有URL:/Product/Details/5,这个URL将会被解析为如下3部分:

Controller = ProductController

Action = Details

Id = 5

默认的路由包含所有3个分段的默认值。默认的控制器是HomeController,默认的动作是Index,默认的Id是一个空字符串。

再比如有URL:/Employee,这个URL将被解析为如下3个参数:

Controller = EmployeeController

Action = Index

Id = ""

最后,如果打开一个ASP.NET MVC应用程序而不提供任何的URL(例如,http://localhost),然后这个URL将会被解析成如下3个参数:

Controller = HomeController

Action = Index

Id = ""

这个请求被发送到HomeController类的Index()动作。

10.6.3 创建自定义路由

对于简单的ASP.NET MVC 4 Web应用程序,默认的路由表已经可以很好地完成工作了。然而,很多时候还是需要创建一个自定义路由。

比如,在ProductController控制器中添加一个动作方法,代码如下。

public string Detail(int id)
{
  return id.ToString ()+".html显示的详细内容...";
}

按照默认URL路由配置,就只能以“/Product/Detail/53”来访问。如果希望用“/prod/detail-53”来访问该方法,就可以在RouteConfig.cs文件中,增加新的路由配置来完成,此时完整的RouteConfig.cs源代码如下。

public class RouteConfig
  {
    public static void RegisterRoutes(RouteCollection routes)
    {
       routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

       routes.MapRoute(
          name:"product_detail_route",
          url:"prod/detail-{id}",
          defaults:new{controller="Product",action ="Detail",id
          = UrlParameter.Optional }
       );
       routes.MapRoute(
          name: "Default",
          url: "{controller}/{action}/{id}",
          defaults:new{controller="Home",action= "Index",id =
          UrlParameter.Optional }
       );
    }
  }

必须注意,添加到路由表中的路由顺序非常重要。新自定义product_detail_route路由在现有的Default路由前面。如果将这个顺序颠倒过来,那么Default路由将总是被调用,而从来不会调用自定义路由product_detail_route。

如此定义后,就可以“/prod/detail-53”的URL来访问ProductController中的Detail方法,访问“/prod/detail-53”运行结果如图10-18所示,当然如果给Detail方法返回了视图,页面就会返回对应视图的输出效果,前提就是要在Views文件夹中定义对应的视图文件。

图10-18 访问“/prod/detail-53”运行结果

10.6.4 创建路由约束

使用路由约束来限制匹配特定路由的浏览器请求。可以使用正则表达式来指定一个路由约束。

以上小节自定义的路由为例来说明。

routes.MapRoute(
          name:"product_detail_route",
          url:"prod/detail-{id}",
          defaults:new{controller="Product",action= "Detail",id
          = UrlParameter.Optional }
       );

代码中定义了一个名称为product_detail_route的路由,注意到Product控制器公布的Detail()动作接受一个称为id的参数。这个参数是一个整数参数。于是,路由会匹配下面的任意URL:“/prod/detail-23”,“/prod/detail-abcd”,但是由于Detail()动作期望的是一个整数值,发起一个含有非整数值的请求将会导致错误。如果在浏览器中输入“/prod/detail-abcd”的URL,那么将会得到如图10-19所示的错误页。

图10-19 访问“/prod/detail-abcd”显示结果(1)

实际想做的是只匹配包含合适整数id的URL。当自定义路由限制与路由相匹配的URL时,就可以使用约束定义。下面的代码就是修改后的product_detail_route路由,它包含一个正则表达式来限制只匹配数字。

routes.MapRoute(
              name:"product_detail_route",
              url:"prod/detail-{id}",
              defaults: new { controller = "Product", action =
              "Detail", id = UrlParameter.Optional },
              constraints: new { id = @"\d+" }
            );

此时,再访问“/prod/detail-abcd”的URL,那么将会得到如图10-20所示的错误页,这是比较合适的错误提示页。

图10-20 访问“/prod/detail-abcd”显示结果(2)

上一篇:10.5理解控制器

下一篇:10.7理解视图

相关教程

共有条评论 网友评论

验证码: 看不清楚?