ASP.NET MVC路由机制详解

对于从ASP.NET WebForms背景转向MVC的开发者来说,理解请求是如何映射到控制器的动作方法,最终在屏幕上渲染视图,可能会感到有些困难。在WebForms中,请求实际上是映射到应用程序目录中实际存在的页面上。但在ASP.NET MVC中,每个请求都需要映射到一个控制器。ASP.NET MVC中没有物理ASPX文件的概念。

在ASP.NET MVC中,有控制器。每个控制器将有多个动作,每个动作都应该处理一个用户请求。用户请求的URL是如何映射到控制器的动作方法的呢?答案是ASP.NET MVC中的路由机制。路由是用户请求的URL和控制器的动作方法之间的桥梁。路由负责映射请求URL到控制器和动作方法的映射策略。

这并不意味着必须手动将所有URL映射到控制器和动作。ASP.NET MVC提供了一种通过指定路由来自动化路由的机制,这些路由是一些提示/模式。这些提示/模式将让路由模块理解请求URL和相应的控制器和动作来调用。

为了让路由引擎更好地理解,可以在路由中指定以下内容: patterns: 这有助于解析器理解如何分解请求URL并将它们映射到特定的控制器和动作。 route parameters: 这让引擎理解传入路由的参数,并将它们映射到动作方法的参数。 route constraints: 这让解析器知道传递的参数类型(字符串/整数)。 ignore rules: 这让解析器知道应该忽略哪些路由或路由模式。

为了更好地理解上述概念,让创建一个简单的空MVC 4 Web应用程序。将看看如何为这个应用程序指定各种路由。 所有路由信息都存储在一个名为 RouteCollection 的集合中。如果想为应用程序指定路由模式,需要在应用程序启动时将这些模式添加到这个集合中。MVC 4项目模板已经在 RouteCollection 中添加了一个默认路由。这个默认路由存在于 RouteConfig.cs 文件的 RegisterRoutes 方法中。这个方法是从 global.asax 文件的 Application_Start 生命周期事件中调用的。让看看这个默认路由,并尝试理解模式。

C# routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }); 第一个属性是路由的名称。添加到路由集合中的每个路由都应该有一个唯一的名称,以便它可以被唯一识别。第二个属性是URL,它指定了请求URL的模式 {controller}/{action}/{id} 。所以如果用户请求一个URL,如: www.example.com/Customer/Edit/1 ,这个URL将调用Customer控制器的Edit动作方法,参数id为1。第三个属性指定了控制器、动作和id参数的默认值。即如果用户请求 www.example.com ,由于URL中缺少控制器、动作和id部分,路由引擎将采用默认值,并调用Home控制器的Index动作,没有id参数(因为它被指定为可选)。

现在脑海中出现的第一个问题是 - 如果需要向动作方法提供2个参数怎么办。这相当容易做到。只需要在路由中指定多个参数值: C# routes.MapRoute( name: "multipleparams", url: "{controller}/{action}/{param1}/{param2}", defaults: new { controller = "Home", action = "Action2", param1 = UrlParameter.Optional, param2 = UrlParameter.Optional }); 以类似的方式,可以在路由模式中指定任意数量的路由参数。同时,可以选择使这些参数中的任何一个为可选。

路由约束主要用于限制与特定路由匹配的请求URL,这可以用来限制对应用程序无效的路由。路由约束以正则表达式的形式指定。让通过定义一个简单的动作方法来编辑一个实体来理解问题。让为它定义一个动作方法。 C# public class HomeController : Controller { public ActionResult Edit(int id) { ViewBag.Message = "Home/Edit/" + id; return View(); } } 现在这个动作方法期望传递一个整数值。这个动作方法有一个视图,它简单地显示路由。所以让用以下URL调用这个动作方法: Home/Edit/1 。结果将是:

发生的事情是,默认路由足以使路由引擎解析请求的URL并调用Edit动作。现在让尝试传递一个无效的整数值在路由中,即 Home/Edit/test 。现在的结果是: 发生这种情况的原因是,非整数值对于这个动作方法来说不是有效的。因此,对于应用程序来说,这是一个无效的路径,为了将这个路径标记为无效路径,可以定义一个带有路由约束的自定义路由。让尝试定义这个带有路由约束的路由。 C# routes.MapRoute( name: "home_Edit", url: "Home/Edit/{id}", defaults: new { controller = "Home", action = "Edit" }, constraints: new { id = @"\d+" }); 这个路由现在只接受这个路由的有效数字值。现在如果再次尝试访问同一个URL,浏览器将清楚地表明这是一个无效的URL。

忽略一些路由 在某些场景中,也希望完全忽略一些路由。如果查看 RouteConfig 类,可以看到类似这样的代码: C# routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 这样做是限制访问所有以 .axd 扩展名结尾的URL,因为不希望最终用户能够访问Trace.axd或其他资源axd文件。

在结束这个小提示之前,有一件重要的事情要记住。将路由插入到 RouteCollection 中的顺序非常重要。路由模块即路由处理器将从上到下开始查找这个映射。所以如果需要将一些特定的路由与通用路由一起放置,应该将特定的路由放在通用路由之前。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485