和Razorpage:Route类似,MVC还是要先要route,但是:
- MVC route的endpoint是:Controller和Action
- route data 作为Action参数使用
- 配置的位置和方式有所不同
默认配置
route配置在RouteConfig.RegisterRoutes()方法中,一般不予修改(即:实际上还是可以更改)。
routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } );
name:开发者自定(比如改成HomeIndex),不能重复。一个MapRoute()方法定义一条route规则
url:
- {controller}和{action},不能修改,对应着应使用的controller和action,比如输入的url是 /Article/Category,对应的是ArticleController下的Category()
- {id}:route data的名字,可由开发者自定义(比如改成name),比如输入的url是 /Article/Category/12,MVC会将12解析成Category(int id)的参数id的值
defaults:
id = UrlParameter.Optional,说明id是可选的。比如/Article/Category没有id仍然是可以匹配这条规则的。
当url中没有{controller}或{action}时,使用的controller和action,比如输入的url是:
- /Article,匹配不了Action,就只有使用默认的Index()
- /,匹配不了Controller和Action,就只有使用默认的HomeController和Index()
演示:改动defaults并进行匹配
自定义配置
可以在RegisterRoutes()中添加更多的MapRoute()方法,制定更多的Route规则。比如:
routes.MapRoute( name: "ArticleSingle", url: "Article/{id}", defaults: new { controller = "Article", action = "Single" } );
这就:
- 为MVC添加了一个名为“ArticleSingle”的route规则,
- 该规则能匹配以Article开头的,后面接着一个{id}值的url,比如:/Article/23,
- 并将该HttpRequest请求交给ArticleController下的Single() Action处理
注意:MVC中的route规则,优先级按其在RegisterRoutes中注册(书写)的先后顺序从高到低排列。比如把这个自定义规则放在Default规则之前,url:/Article/Category虽然能匹配Default规则,但会被ArticleSingle“截断”!(_演示_)
constraints
MVC的constraint需要使用正则表达式:
routes.MapRoute( name: "ArticleSingle", url: "Article/{id}", defaults: new { controller = "Article", action = "Single" }, constraints: new { id = @"d*" } //只能是数字 );
这样,/Article/Category就不能匹配ArticleSingle了 (Category不是数字)
[Route]特性
MVC可以在Action上添加一个[Route]特性,template和RazorPage配置相似。
最新版本_(5.0以后)_需要显式开启
public static void RegisterRoutes(RouteCollection routes) { routes.MapMvcAttributeRoutes();
因为这种方式没有先后顺序区分优先级,所以还额外配置了Order属性。
但是,不推荐:
- 散乱,不便于维护
- 引入Order,更乱
伪静态
有时候客户会要求url是这种带着html后缀名格式:/Home/Index/3.html
你可能会想到,简单,RegisterRoutes()中调整一下就OK,比如:
routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}.html",
演示:无法实现route
因为ASP.NET会首先根据请求文件类型_(文件名后缀)_判断是否进行route。默认的,html文件被视为静态文件请求,不会进入route.
所以需要在web.config中添加:
告诉ASP.NET对所有请求(All Reuests)使用route(All Managed Modules)。