网址路由(Routing)在ASP.NET MVC中有两个主要目的:第一,比对通过浏览器传来的HTTP要求;第二,相应适当的网址给浏览器。
一、Routing——网址路由
1、比对通过浏览器传来的HTTP要求
点击链接后,浏览器将URL转换成HTTP要求的封包,并且由浏览器发出HTTP要求到服务器上,这时会先由IIS接收到这个HTTP封包,然后再转交给网址路由模块负责决定将此HTTP要求交由哪个HTTPHandler处理。
2、响应适当的网址给浏览器
示例1:
@Html.ActionLink("关于","About","Home")
以上代码,将会输出以下HTML超链接:关于
3、默认网址路由属性解说
默认的网址路由规则定义在APP_Start\RouteConfig.cs文档中,文件路径是根目录中自动会生成的一个Global.asax.cs文件。Application_Start()方法会在网站启动时自动调用。
其中,RouteTable.Routes是一个公开的静态对象,用来保存所有网址路由的规则集(RouteCollection),默认执行Application_Start()方法时,将RouteTable.Routes变量传入RouteConfig.RegisterRoutes静态方法:RouteConfig.RegisterRoutes(RouteTable.Routes) 。
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
//注册 mvc应用程序中的所有区域
AreaRegistration.RegisterAllAreas();
//注册 全局的Filters
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
//注册 路由规则
RouteConfig.RegisterRoutes(RouteTable.Routes);
//注册 打包绑定(js , css 等)
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
默认RouteConfig.RegisterRoutes方法中的IgnoreRoute,定义的URL样式所代表的含义是:只要网址中出现任何.axd结尾的网址,而且该网址后面出现任何路径,都会被视为跳过网址路由的网址。这样的网址将会改由IIS的其它模块(HttpModules)进行处理,并且也不再与ASP.NET MVC相关,所以也不会进入ASP.NET MVC运行生命周期。
默认RouteConfig.RegisterRoutes方法中MapRoute,则是最常用来定义的网址路由的扩充方法。自C#4.0后,定义“具名参数”的语法,使调用方法变得非常直观和方便,参数可以设置默认值,且不用每个参数都输入。
(1)name参数定义Route名称,在此为“Default”。
(2)url具名参数定义URL样式与每个路径段落(PathSegment)的RouteValue参数名称。也就是说我们定义的URL样式包含三个路由参数,分别命名为controller、action与id。
(3)defaults具名参数定义RouteValue路由参数默认值,当网址路由比对不到HTTP要求网址时,会尝试带入这里定义的默认值,然后进一步比对是否由符合的Controller和Action可以运行。
注意:之所以访问http://www.xx.com/ 这样的URL网址能正确返回,是因为我们设置了URL段的默认值,相当于访问:
http://www.xx.com/Home/Index
public class RouteConfig
{
///
/// 注册路由的方法
///
/// 路由集合,既然是集合肯定能添加多个路由规则,这部分在之后会介绍。
public static void RegisterRoutes(RouteCollection routes)
{
//忽略给定可用路由列表的指定URL路由
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//路由映射,映射指定的URL路由并设置默认路由值
routes.MapRoute(
name: "Default",//要映射的路由的名称。
url: "{controller}/{action}/{id}",//路由的 URL 模式。{控制器}/{操作}/{参数}
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
示例1:http://localhost/Member/Detail?id=123
Member对应Map Route的controller;Detail对应Map Route的action;?id=123不算是网站路径的一部分,而属于QueryString的范围,但是 QueryString并不算在网址路由之中,所以不会算进RouteValue中。
至此,所有网址路径的路径段落(PathSegment)已经比对完毕,所以只剩下{id}没比对到,在比对不成功之后,网址路由会自动读取default具名参数的设置,也就是读得id路由参数的默认值UrlParameter.Optional,所以最后比对成果是{id}比对成功。Routing模块会把此次HTTP要求委托给MvcHandler负责处理,而MvcHandler会通过当前已经取得的RouteValue路由参数查找对应的Controller和Action来运行程序,所以就会跑去运行MemberController控制器中的Detail动作。
实例2:替网址路由加上路由值的条件约束
MapRoute方法,使用constraints这个具名参数替路由值加上一些条件约束,这些条件约束是以.NET Framework正则表达式为格式,通过正则表达式来验证路由值的属性是否符合该样式。
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
//加上路由值的条件约束-{id}路由值的属性全部为“数字”
constrains:new {
id = @"\d+"
}
);
目的:
在Controller或View中根据网址路由定义生成适当的网址。
方法一:使用View数据呈现技术中的HTML Helper来生成网址;
方法二:使用RouteTable.Routes.GetVirtualPath静态方法取得ASP.NET MVC里面动态生成的网址。
比对:MVC笔记 网址路由与MVC的生命周期