我们知道在ASP.NET Web Forms中,一个URL请求往往对应一个aspx页面,一个aspx页面就是一个物理文件,它包含对请求的处理。
而在ASP.NET MVC中,一个URL请求是由对应的一个Controller中的Action来处理的,由URL Routing来告诉MVC如何定位到正确的Controller和Action。
笼统的讲,URL Routing包含两个主要功能:解析URL 和 生成URL,本文将围绕这两个大点进行讲解。
本文目录
让我们从下面这样一个简单的URL开始:
http://mysite.com/Admin/Index
在域名的后面,默认使用“/”来对URL进行分段。路由系统通过类似于 {controller}/{action} 格式的字符串可以知道这个URL的 Admin 和 Index 两个片段分别对应Controller和Action的名称。
默认情况下,路由格式中用“/”分隔的段数是和URL域名的后面的段数是一致的,比如,对于{controller}/{action} 格式只会匹配两个片段。如下表所示:
URL路由是在MVC工程中的App_Start文件夹下的RouteConfig.cs文件中的RegisterRoutes方法中定义的,下面是创建一个空MVC项目时系统生成的一个简单URL路由定义:
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); }
静态方法RegisterRoutes是在Global.asax.cs文件中的Application_Start方法中被调用的,除了URL路由的定义外,还包含其他的一些MVC核心特性的定义:
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); }
前面讲的都是解析URL的部分,现在我们来看看如何通过路由系统在View中生成URL。
在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 an outgoing URL", "CustomVariable") </div> ...
这里的Html.ActionLink方法将会生成指向View对应的Controller和第二个参数指定的Action,我们可以看看运行后页面是如何显示的:
经过查看Html源码,我们发现它生成了下面这样的一个html链接:
<a href="/Home/CustomVariable">This is an outgoing URL</a>
这样看起来,通过Html.ActionLink生成URL似乎并没有直接在View中自己写一个<a>标签更直接明了。 但它的好处是,它会自动根据路由配置来生成URL,比如我们要生成一个指向HomeContrller中的CustomVariable Action的连接,通过Html.ActionLink方法,只需要给出对应的Controller和Action名称就行,我们不需要关心实际的URL是如何组织的。举个例子,我们定义了下面的路由:
public static 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 }); }
运行程序,我们发现它会自动生成下面这样的连接:
<a href="/App/DoCustomVariable">This is an outgoing URL</a>
所以我们要生成指向某个Action的链接时,最好使用Html.ActionLink方法,否则你很难保证你手写的连接就能定位到你想要的Action。
上面我们给Html.ActionLink方法传递的第二个参数只告诉了路由系统要定位到当前View对应的Controller下的Action。Html.ActionLink方法可以使用第三个参数来指定其他的Controller,如下所示:
<div> @Html.ActionLink("This targets another controller", "Index", "Admin") </div>
它会自动生成如下链接:
<a href="/Admin">This targets another controller</a>
有时候我们想在连接后面加上参数以传递数据,如 ?id=xxx 。那么我们可以给Html.ActionLink方法指定一个匿名类型的参数,如下所示:
<div> @Html.ActionLink("This is an outgoing URL", "CustomVariable", new { id = "Hello" }) </div>
它生成的Html如下:
<a href="/Home/CustomVariable/Hello">This is an outgoing URL</a>
通过Html.ActionLink方法生成的链接是一个a标签,我们可以在方法的参数中给标签指定Html属性,如下所示:
<div> @Html.ActionLink("This is an outgoing URL", "Index", "Home", null, new {id = "myAnchorID", @class = "myCSSClass"}) </div>
这里的class加了@符号,是因为class是C#关键字,@符号起到转义的作用。它生成 的Html代码如下:
<a class="myCSSClass" href="/" id="myAnchorID">This is an outgoing URL</a>
用Html.ActionLink方法生成一个html链接是非常有用而常见的,如果要生成URL字符串(而不是一个Html链接),我们可以用 Url.Action 方法,使用方法如下:
<div>This is a URL: @Url.Action("Index", "Home", new { id = "MyId" }) </div>
它显示到页面是这样的: