ASP.NET MVC5路由系统机制详细讲解
请求一个ASP.NET mvc的网站和以前的web form是有区别的,ASP.NET MVC框架内部给我们提供了路由机制,当IIS接受到一个请求时,会先看是否请求了一个静态资源(.html,css,js,图片等),这一步是web form和mvc都是一样的,如果不是则说明是请求的是一个动态页面,就会走asp.net的管道,mvc的程序请求都会走路由系统,会映射到一个Controller对应的Action方法,而web form请求动态页面是会查找本地实际存在一个aspx文件。下面通过一个ASP.NET MVC5项目来详细介绍一下APS.NET MVC5路由系统的机制。
一、认识Global.asax.cs
1 public class MvcApplication : System.Web.HttpApplication
2 {
3 protected void Application_Start()
4 {
5 //注册 ASP.NET MVC 应用程序中的所有区域
6 AreaRegistration.RegisterAllAreas();
7 //注册 全局的Filters
8 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
9 //注册 路由规则
10 RouteConfig.RegisterRoutes(RouteTable.Routes);
11 //注册 打包绑定(js,css等)
12 BundleConfig.RegisterBundles(BundleTable.Bundles);
13 }
14 }
这个Application_Start方法会在网站启动的自动调用,其中我们看到:RouteConfig.RegisterRoutes(RouteTable.Routes);这个就是向ASP.NET MVC 框架注册我们自定义的路由规则,让之后的URL能够对应到具体的Action。接下来我们再来看看RegisterRoutes方法做了些什么?
1 public class RouteConfig
2 {
3 public static void RegisterRoutes(RouteCollection routes)
4 {
5 routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
6 routes.MapRoute(
7 name: "Default",
8 url: "{controller}/{action}/{id}",
9 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
10 );
11 }
12 }
二、ASP.NET MVC默认的命名约定
1、Controller命名约定
2、View命名约定
三、ASP.NET MVC的URL规则说明

1 routes.MapRoute(
2 name: "Default",
3 url: "{controller}/{action}/{id}",
4 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
5 );
|
URL
|
URL段 |
|
http://mysite.com/Admin/Index
|
controller = Admin
action = Index
|
|
http://mysite.com/Index/Admin
|
controller = Index
action = Admin
|
|
http://mysite.com/Apples/Oranges
|
controller = Apples
action = Oranges
|
|
http://mysite.com/Admin
|
无匹配-段的数量不够
|
|
http://mysite.com/Admin/Index/Soccer
|
无匹配-段的数量超了 |
四、mvc创建一个简单的Route规则
1 public static void RegisterRoutes(RouteCollection routes) {
2
3 routes.MapRoute("MyRoute", "{controller}/{action}");
4 }
用到了RouteCollection的MapRoute方法。其实我们还可以调用 Add方法,传一个Route的实例给它一样的达到相同的效果。
1 public static void RegisterRoutes(RouteCollection routes) {
2
3 Route myRoute = new Route("{controller}/{action}", new MvcRouteHandler());
4 routes.Add("MyRoute", myRoute);
5 }
五、mvc路由的默认值的设定
1 public static void RegisterRoutes(RouteCollection routes) {
2 routes.MapRoute("MyRoute", "{controller}/{action}", new { action = "Index" });
3 }
要设置Controller和Action的默认值。
1 public static void RegisterRoutes(RouteCollection routes) {
2
3 routes.MapRoute("MyRoute", "{controller}/{action}",
4 new { controller = "Home", action = "Index" });
5 }
|
Url段的数量
|
实例
|
Route映射
|
|
0
|
mydomain.com
|
controller = Home
action = Index
|
|
1
|
mydomain.com/Customer
|
controller = Customer
action = Index
|
|
2
|
mydomain.com/Customer/List
|
controller = Customer
action = List
|
|
3
|
mydomain.com/Customer/List/All
|
无匹配—Url段过多
|
六、mvc使用静态URL段
1 public static void RegisterRoutes(RouteCollection routes) {
2
3 routes.MapRoute("MyRoute", "{controller}/{action}",
4 new { controller = "Home", action = "Index" });
5
6 routes.MapRoute("", "Public/{controller}/{action}",
7 new { controller = "Home", action = "Index" });
8 }
1 public static void RegisterRoutes(RouteCollection routes) {
2
3 routes.MapRoute("", "X{controller}/{action}");
4
5 routes.MapRoute("MyRoute", "{controller}/{action}",
6 new { controller = "Home", action = "Index" });
7
8 routes.MapRoute("", "Public/{controller}/{action}",
9 new { controller = "Home", action = "Index" });
10
11 }
七、mvc的路由中自定义参数变量
1 public static void RegisterRoutes(RouteCollection routes) {
2
3 routes.MapRoute("MyRoute", "{controller}/{action}/{id}",
4 new { controller = "Home", action = "Index", id = "1" });
5 }
1 public ViewResult CustomVariable() {
2
3 ViewBag.CustomVariable = RouteData.Values["id"];
4 return View();
5 }
1 public ViewResult CustomVariable(int id) {
2
3 ViewBag.CustomVariable = id;
4 return View();
5 }
MVC框架使用内置的Model绑定系统将从URL获取到变量的值转换成Action参数相应类型的值。这种转换除了可以转换成基本int,string等等之外还可以处理复杂类型,自定义的Model,List集合等。
八、mvc定义可选URL段、可选参数
1、注册路由时定义可选URL段
2、通过Action参数来定义可选参数
九、mvc使用*来定义变长数量的URL段
|
Url段的数量
|
实例
|
Route映射
|
|
0
|
mydomain.com
|
controller = Home
action = Index
|
|
1
|
mydomain.com/Customer
|
controller = Customer
action = Index
|
|
2
|
mydomain.com/Customer/List
|
controller = Customer
action = List
|
|
3
|
mydomain.com/Customer/List/All
|
controller = Customer
action = List
id = All
|
|
4
|
mydomain.com/Customer/List/All/Delete
|
controller = Customer
action = List
id = All
catchall = Delete
|
|
5
|
mydomain.com/Customer/List/All/Delete/Perm
|
controller = Customer
action = List
id = All
catchall = Delete /Perm
|
十、mvc使用命名空间来为路由的Controller类定优先级
1 public static void RegisterRoutes(RouteCollection routes) {
2
3 routes.MapRoute("Default",
4 "{controller}/{action}/{id}",
5 new { controller = "Home", action = "Index", id = UrlParameter.Optional },
6 new string[] { "WebApplication1.Controllers" }
7 );
8 }
十一、mvc定义路由规则的约束
1、用正则表达式限制asp.net mvc路由规则
1 public static void RegisterRoutes(RouteCollection routes) {
2
3 routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
4 new { controller = "Home", action = "Index", id = UrlParameter.Optional },
5 new { controller = "^H.*"},
6 new[] { "URLsAndRoutes.Controllers"});
7 }
2、把asp.net mvc路由规则限制到到具体的值
1 public static void RegisterRoutes(RouteCollection routes) {
2
3 routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
4 new { controller = "Home", action = "Index", id = UrlParameter.Optional },
5 new { controller = "^H.*", action = "^Index$|^About$"},
6 new[] { "URLsAndRoutes.Controllers"});
7 }
上例在controller和action上都定义了约束,约束是同时起作用是,也就是要同时满足。上面表示只匹配contorller名字以H开头的URL,且action变量的值为Index或者为About的URL。
3、把asp.net mvc路由规则限制到到提交请求方式(POST、GET)
1 public static void RegisterRoutes(RouteCollection routes) {
2
3 routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
4 new { controller = "Home", action = "Index", id = UrlParameter.Optional },
5 new { controller = "^H.*", action = "Index|About",
6 httpMethod = new HttpMethodConstraint("GET") },
7 new[] { "URLsAndRoutes.Controllers" });
8 }
上面表示只匹配为GET方式的请求。
4、使用接口IRouteConstraint自定义一个asp.net mvc路由约束
1 using System.Web;
2 using System.Web.Routing;
3
4 namespace URLsAndRoutes.Infrastructure {
5
6 public class UserAgentConstraint : IRouteConstraint {
7 private string requiredUserAgent;
8
9 public UserAgentConstraint(string agentParam) {
10 requiredUserAgent = agentParam;
11 }
12
13 public bool Match(HttpContextBase httpContext, Route route, string parameterName,
14 RouteValueDictionary values, RouteDirection routeDirection) {
15
16 return httpContext.Request.UserAgent != null &&
17 httpContext.Request.UserAgent.Contains(requiredUserAgent);
18 }
19 }
20 }
asp.net mvc自定义路由约束的使用:
1 public static void RegisterRoutes(RouteCollection routes) {
2
3 routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
4 new { controller = "Home", action = "Index", id = UrlParameter.Optional },
5 new {
6 controller = "^H.*", action = "Index|About",
7 httpMethod = new HttpMethodConstraint("GET", "POST"),
8 customConstraint = new UserAgentConstraint("IE")
9 },
10 new[] { "URLsAndRoutes.Controllers" });
11 }
十二、mvc将URL路由到磁盘文件
1 public static void RegisterRoutes(RouteCollection routes) {
2
3 routes.RouteExistingFiles = true;
4
5 routes.MapRoute("DiskFile", "Content/StaticContent.html",
6 new {
7 controller = "Account", action = "LogOn",
8 },
9 new {
10 customConstraint = new UserAgentConstraint("IE")
11 });
12
13 routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
14 new { controller = "Home", action = "Index", id = UrlParameter.Optional },
15 new {
16 controller = "^H.*", action = "Index|About",
17 httpMethod = new HttpMethodConstraint("GET", "POST"),
18 customConstraint = new UserAgentConstraint("IE")
19 },
20 new[] { "URLsAndRoutes.Controllers" });
21 }
我们把RouteExistingFiles属性设置为true,表示存在的文件也走路由,上面我们把Content/StaticContent.html这个文件映射到controller 为Account,action 为LogOn中了,而并不是指磁盘中存在的文件。基于asp.net mvc的这个特性我们就可以实现mvc以.html结尾的伪静态
十三、mvc跳过、绕开路由系统设定
1 public static void RegisterRoutes(RouteCollection routes) {
2
3 routes.RouteExistingFiles = true;
4
5 routes.MapRoute("DiskFile", "Content1/StaticContent.html",
6 new {
7 controller = "Account", action = "LogOn",
8 },
9 new {
10 customConstraint = new UserAgentConstraint("IE")
11 });
12
13 routes.IgnoreRoute("Content/*{filename}");
14 routes.MapRoute("", "{controller}/{action}");
15
16 }


浙公网安备 33010602011771号