在MVC的项目中有一个Global.asax.cs 文件,里面有一个 Application_Start 方法,代码如下:
public class MvcApplication : System.Web.HttpApplication { /// <summary> ///不是每次请求都调用 ///在Web应用程序的生命周期里就执行一次 ///在应用程序第一次启动和应用程序域创建时被调用 ///适合处理应用程序范围的初始化代码 /// </summary> protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes);//注册路由 BundleConfig.RegisterBundles(BundleTable.Bundles); } }
这个地方就是开启路由的地方,它把url包装成Route对象,然后把我们注册的路由规则用name---route键值对的方式存入RouteCollection中(注册的路由写在App_Start 文件加下面的 RouteConfig 里面),当请求来了后,会在RouteCollection进行路由解析,就会根据自定义的路由规则从上到下进行匹配
路由解析:
1.如果没有匹配上我们定义的路由,那么就走原始流程,就等于MVC中路由完全没有生效
2.如果请求能够找到物理文件,那么就不再匹配路由(支持WebForm的原因)
3.匹配路由是从上到下进行匹配的,如果第一个匹配上了,那么就不会继续往下匹配了,如果匹配不上,那么就走原始流程
WebForm请求:
WebForm请求的是一个具体的页面,当用户请求具体的aspx页面时,服务器会对该页面中的内容一行一行的解析(碰到服务器脚本语言还会执行),最后形成响应流重新写回到浏览器,再由浏览器对该响应流进行解析(依照W3C标准),最终将用户请求的页面呈现出来
注册路由的几种方式如下:
1.在RouteConfig 里面注册路由
参数说明:
name: 路由名称
url: url参数
defaults: 参数默认值
constraints: 参数约束(常用的是正则表达式)
/* 默认路由规则 这个表示只匹配所有控制器下面的动作,如果不指定控制器和动作,那么默认访问Home控制器下的Index动作,如果指定了,那么就访问指定的控制器下的动作 */ routes.MapRoute( name: "Default1", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); /* 指定控制器(就是把控制器写死) 这个表示只匹配Home控制器下面的动作,如果不指定动作,那么默认访问Index动作,如果指定了,那么就访问指定的动作 */ routes.MapRoute( name: "Default2", url: "Home/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); /* 指定控制器和动作(就是把控制器和动作写死) 这个表示只匹配Home控制器下面Index动作 */ routes.MapRoute( name: "Default3", url: "Home/Index/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); /* 给路由定义约束(constraints) 这个表示只能匹配Home和Index控制器下面的Index方法 */ routes.MapRoute( name: "Default4", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }, constraints: new { controller = "Home|Index", action = "Index" } ); /* 给路由定义约束(constraints) 这个表示只能匹配Home和Index控制器下面的Index方法,并且一定要带一个参数 id,不管动作是否需要参数,不带访问不到啊(例如:localhost:8955/Index/Index_100) 这样写的好处是GET请求的时,让别人不知到你这参数是干什么的,是什么字段 注意: 这个地方可以随意拼接例如:{controller}_{id}/{action} {controller}/{action}/_{id} */ routes.MapRoute( name: "Default4", url: "{controller}/{action}/_{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }, constraints: new { controller = "Home|Index", action = "Index" } ); /* 给路由定义约束(constraints)----正则表达式 这个表示 1.只能匹配Home和Index控制器下面的Index方法,并且一定要带一个参数 id, 2.并且id的值是五个数字组成 (例如:localhost:8955/Home/Index_10000) 3.此路有之匹配GET请求 */ routes.MapRoute( name: "Default4", url: "{controller}/{action}_{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }, constraints: new { controller = "Home|Index", action = "Index",id=@"\d{5}",httpMethod = new HttpMethodConstraint("GET") } );