传统的ASP.NET web form 是假想,用户请求的URL和服务器上面的文件之间有某种关联,这里,服务器的工作就是根据接收到的用户请求,检索到对应的文件给用户。这种方式在web form时代很适合,因为ASP.NET页面是aspx页面,并且能够独立的回复用户的浏览器请求。 但是这中方式在MVC中不合适,在MVC中用户请求是通过控制器里面的方法来处理的,在MVC中没有ASP.NET,一对一的文件关联关系;为了解决这个问题,我们要学会MVC路由机制。
路由机制有两个功能:
1.检查收到的URL请求,来判断这个请求是要请求哪个控制器哪个方法的;
2.生成外部URL(用户点击某个链接的时候,会有一个请求,通过视图展现在浏览器上面的URL)
现在我们来开始学MVC路由配置吧:
在MVC 框架中,有两种方式创建路由:
1.基于约定的路由配置
2.特定的路由配置
你可能已经很熟悉了基于约定的路由配置,但是特定的路由配置是MVC5中新增加的。我们在这里都会学习
路由机制不知道,什么是(Controller)控制器,什么是(Actions)方法,它只是提取URL片段,路由的请求处理在后面的处理中,当满足路由配置的时候,才能得到请求的页面;
默认的,路由会匹配拥有正确的片段的URL,例如{controller}/{action},会匹配有两个片段的URL
URL模式是保守的,只会匹配拥有同样的片段的URL,但是URL模式又是包容的,只要URL有正确的片段,就会检查片段的值,但不论值是啥。
路由配置是在RouteConfig.cs文件中的;
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 } ); routes.MapRoute( name: "Student", url: "student/{id}", defaults: new { controller = "Student", action = "Index"}, constraints: new { id = @"d+" } ); }
RegisterRoutes这个静态方法在Global.asax文件中被调用,程序每次运行的时候,会执行Global文件中的Application_Start()方法,进行路由注册;
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); }
路由机制概述
1.匹配传入的请求(该请求不匹配服务器文件系统中文件),并将这些请求映射到控制器操作(Controller中的action方法)
MVC基本的处理流程:来了一个URL请求, 从中找到Controller和Action的值, 将请求传递给Controller处理. Controller获取Model数据对象, 并且将Model传递给View, 最后View负责呈现页面。(说白了,就是来了一个URL,找到一个控制器中的方法)(路由是模式,有参数,通过URL中的参数,就可以对应找到符合这种路由模式的方法)
Routing的作用:
routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "GlobalIndex", id = UrlParameter.Optional } );
路由URL模式 |
默认值 |
匹配URL模式的实例 |
{controller}/{action}/{id} |
New {id=“”} |
/albums/display/123 /albums/display |
{controller}/{action}/{id} |
New {controller=“home”, action=“index”, id=“”} |
/albums/display/123 /albums/display /albums / |
public ActionResult Index()
public ActionResult Index(int id)
在页面中有一个请求
类型 MVCDemo.Controllers.TestController 的 System.Web.Mvc.ActionResult Index()
类型 MVCDemo.Controllers.TestController 的 System.Web.Mvc.ActionResult Index(Int32)
routes.MapRoute("showBlogRoute", "blog/post/{id}", new { controller =“CMS”,action = “Show”,id=“”}); routes.MapRoute("blogRoute", “blog/{action}/{id}", new { controller = "CMS", action = “Index", id = “”}); routes.MapRoute(“DefaultRoute”, // 路由名称 "{controller}/{action}/{id}", // 带有参数的 URL new { controller = "Home", action = "Index", id =“”} // 参数默认值 );
routes.MapRoute("simple", "archive/{year}/{month}/{day}", new{controller="blog",action="search",year="2009",month="10",day="10"}, new{ year=@"d{2}|d{4}",//只能是两位或四位数字 month=@"d{1,2}",//只能使用一位或两位数字 day=@"d{1,2}"//只能使用一位或两位数字 });
2.构造传出的URL,用来响应控制器中的操作
<div> @Html.ActionLink("点击","Click","Home"); </div>
RouteCollection. GetVirtualPath方法
方法 |
说明 |
如果具有指定的上下文和参数值,则返回与路由关联的 URL 路径的相关信息。 |
|
GetVirtualPath(RequestContext, String, RouteValueDictionary) |
如果具有指定的上下文、路由名称和参数值,则返回与命名路由关联的 URL 路径的相关信息。 |
第一个方法获得了当前路由的一些信息和用户指定的路由值(字典)去选择目标路由。
1. 路由系统然后会循环整个路由表,通过GetVirtualPath方法向每一个路由发问:“Can you generate a URL given these parameters?”
2. 如果答案是Yes,那么就会返回一个VirtualPathData实例,包括URL和与匹配相关的一些其他信息。如果答案是NO,则返回一个Null,路由系统会转向下一条路由,直到遍历整个路由表。
举例:
如果我们在路由机制中定义了一个
routes.MapRoute( name: "test", url: "test/look/{id}", defaults: new { controller = "Home", action = "Click", id = UrlParameter.Optional } ); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } );
在视图中写:
<div> @Html.ActionLink("测试","look","test"); </div> <div> @Html.ActionLink("点击","Click","Home"); </div>
最终的结果是 不管点击哪一个按钮,都会触发方法Click
public class HomeController : Controller { // // GET: /Home/ public ActionResult Index() { return View(); } public ActionResult Click() { return View(); } }
但是显示的URL都是
如果我们在地址栏中直接输入 test/look或者Home/Click 都是正确的。