技术分享的时候是个分享了路由的知识点,之前没有怎么注意到,听完课之后去回到项目中看代码,在Global.asax中可以看到注册路由的代码。我们了解MVC程序的所有请求都是先经过路由解析然后分配到特定的Controller 以及 Action 中的,因此咱们继续学习。
一、如何解析路由
1. 默认定义方式
routes.MapRoute(
"Default", // 路由名称
"{controller}/{action}/{id}", // 带有参数的 URL
new { controller ="Test", action = "Index", id = UrlParameter.Optional } //定义片段默认值,参数ID是可选的
);
2. 自定义路由
publicstatic void RegisterRoutes(RouteCollection routes) {
routes.MapRoute("NewRoute","App/Do{action}", new { controller = "Home" });
routes.MapRoute("MyRoute","{controller}/{action}/{id}",
new { controller = "Home",action = "Index", id = UrlParameter.Optional });
}
因此当我们重新启动运行程序,我们发现它会自动生成下面这样的连接:
<ahref="/App/DoCustomVariable">This is an outgoing URL</a>
3. 自定义片段变量————增加参数个数
我们可以通过 catchall 片段变量加* 号前缀来定义匹配任意数量片段的路由。如下所示: (使用*catchall,将匹配的任意数量的片段,但我们需要自己通过“/”分隔catchall变量的值来取得独立的片段值。)
routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
4. 路由约束——通过正则表达式,我们可以制定限制URL的路由规则,下面的路由定义限制了controller片段的变量值必须以 H 打头:
routes.MapRoute("MyRoute","{controller}/{action}/{id}",
new { controller = "Home", action= "Index", id = UrlParameter.Optional },
new { controller = "^H.*" }
);
定义路由约束是在MapRoute方法的第四个参数。和定义默认值一样,也是用匿名类型。我们可以用正则表达式约束来定义只有指定的几个特定的片段值才能进行匹配,如下所示,但是限制了action片段值只能是Index或About,不区分大小写。
routes.MapRoute("MyRoute","{controller}/{action}/{id}",
new { controller = "Home", action= "Index", id = UrlParameter.Optional },
new { controller = "^H.*", action= "^Index$|^About$" }
);
二、生成URL(View)
1. ActionLink
a.同一个Controller下的调用
在View中生成URL的最简单方法就是调用Html.ActionLink方法,如下面在 Views/Shared/ActionName.cshtml 中的代码所示:
...
<div>The controller is: @ViewBag.Controller</div>
<div>The action is: @ViewBag.Action</div>
<div>
@Html.ActionLink("This is anoutgoing URL", "CustomVariable")
</div>
...
这里的Html.ActionLink方法将会生成指向View对应的Controller和第二个参数指定的Action,我们可以看看运行后页面是如何显示的:
经过查看Html源码,我们发现它生成了下面这样的一个html链接:
<ahref="/Home/CustomVariable">This is an outgoing URL</a>
它的好处是,它会自动根据路由配置来生成URL,比如我们要生成一个指向HomeContrller中的CustomVariable Action的连接,通过Html.ActionLink方法,只需要给出对应的Controller和Action名称就行,我们不需要关心实际的URL是如何组织的。
所以我们要生成指向某个Action的链接时,最好使用Html.ActionLink方法,否则你很难保证你手写的连接就能定位到你想要的Action。
2.生成其他controller的action链接
上面我们给Html.ActionLink方法传递的第二个参数只告诉了路由系统要定位到当前View对应的Controller下的Action。Html.ActionLink方法可以使用第三个参数来指定其他的Controller,如下所示:
<div>
@Html.ActionLink("This targets anothercontroller", "Index", "Admin")
</div>
它会自动生成如下链接:
<ahref="/Admin">This targets another controller</a>
c.生成带有URL参数的链接
有时候我们想在连接后面加上参数以传递数据,如 ?id=xxx 。那么我们可以给Html.ActionLink方法指定一个匿名类型的参数,如下所示:
<div>
@Html.ActionLink("This is an outgoingURL", "CustomVariable", new { id = "Hello" })
</div>
它生成的Html如下:
<ahref="/Home/CustomVariable/Hello">This is an outgoingURL</a>
d.根据指定的路由名称生成URL——-Html.RouteLink
定义两个路由规则如下:但是永远调不到第二个。
publicstatic void RegisterRoutes(RouteCollection routes) {
routes.MapRoute("MyRoute","{controller}/{action}");
routes.MapRoute("MyOtherRoute","App/{action}", new { controller = "Home" });
}
这时候我们需要通过另一个方法Html.RouteLink来生成URL了,方法如下:
@Html.RouteLink("Clickme", "MyOtherRoute","Index", "Customer")
它会生成如下链接:
<aLength="8" href="/App/Index?Length=5">Click me</a>
这个链接指向的是HomeController下的Index Action。但需要注意,通过这种方式来生成URL是不推荐的,因为它不能让我们从直观上看到它生成的URL指向的controller和action。所以,非到万不得已的情况才会这样用。
e.在Action中重定向——RedirectToAction
更多时候我们会在Action方法中将客户端浏览器重定向到别的URL,这时候我们使用RedirectToAction方法,如下:
publicRedirectToRouteResultMyActionMethod() {
return RedirectToAction("Index");
}
RedirectToAction的返回结果是一个RedirectToRouteResult类型,它使MVC触发一个重定向行为,并调用指定的Action方法。RedirectToAction也有一些重载方法,可以指定controller和其他片段的变量值,如:
publicRedirectToRouteResult MyActionMethod() {
return RedirectToRoute(new { controller ="Home", action = "Index", id = "MyID" });
}
f. 在Action方法中生成URL
通常我们一般在View中才会去生成URL,但也有时候我们需要在Action中生成URL,方法如下:
publicViewResult MyActionMethod() {
string myActionUrl =Url.Action("Index", new { id = "MyID" });
string myRouteUrl = Url.RouteUrl(new {controller = "Home", action = "Index" });
//... do something with URLs...
return View();
}