ASP.NET MVC5 :Attribute路由使用详解
1、什么是Attribute路由?怎么样启用Attribute路由?
微软在 ASP.NET MVC5 中引入了一种新型路由:Attribute路由,顾名思义,Attribute路由是通过Attribute来定义路由。当然,MVC5也支持以前定义路由的方式,你可以在一个项目中混合使用这两种方式来定义路由。
在以前的版本中我们通常在 RouteConfig.cs 文件中通过以下方式来定义路由:
routes.MapRoute(
name: "ProductPage",
url: "{productId}/{productTitle}",
defaults: new { controller = "Products", action = "Show" },
constraints: new { productId = "\\d+" }
);
在MVC5中,我们可以把路由定义和 Action 放在一起:
[Route("{productId:int}/{productTitle}")]
public ActionResult Show(int productId) { ... }
当然,首先得启用Attribute路由,我们可以调用MapMvcAttributeRoutes方法来启用Attribute路由:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
}
}
2、URL可选参数和默认值
我们可以使用问号“?”来标记一个可选参数,也可以对参数设定默认值:
public class BooksController : Controller
{
// 匹配: /books
// 匹配: /books/1430210079
// 问号表示 isbn 是可选的
[Route("books/{isbn?}")]
public ActionResult View(string isbn)
{
if (!String.IsNullOrEmpty(isbn))
{
return View("OneBook", GetBook(isbn));
}
return View("AllBooks", GetBooks());
}
// 匹配: /books/lang
// 匹配: /books/lang/en
// 匹配: /books/lang/he
// 如果URL不传递 lang 参数,则lang的值为“en”
[Route("books/lang/{lang=en}")]
public ActionResult ViewByLanguage(string lang)
{
return View("OneBook", GetBooksByLanguage(lang));
}
}
3、路由前缀
有时候在同一个 Controller 中,所有 Action 匹配的 URL 都拥有相同的前缀,如下:
public class ReviewsController : Controller
{
// 匹配: /reviews
[Route("reviews")]
public ActionResult Index() { ... }
// 匹配: /reviews/5
[Route("reviews/{reviewId}")]
public ActionResult Show(int reviewId) { ... }
// 匹配: /reviews/5/edit
[Route("reviews/{reviewId}/edit")]
public ActionResult Edit(int reviewId) { ... }
}
我们看到 ReviewsController 下的所有 Action 前面都带有 "reviews",这时我们可以在 Controller 上使用 [RoutePrefix]设置路由前缀,为每个 Action 所匹配的 URL 加上共同的前缀 "reviews":
[RoutePrefix("reviews")]
public class ReviewsController : Controller
{
// 匹配: /reviews
[Route]
public ActionResult Index() { ... }
// 匹配: /reviews/5
[Route("{reviewId}")]
public ActionResult Show(int reviewId) { ... }
// 匹配: /reviews/5/edit
[Route("{reviewId}/edit")]
public ActionResult Edit(int reviewId) { ... }
}
但是,如果某一个 Action 不想要这个前缀怎么办?当然有办法,我们可以用波浪号“~”来去掉它:
[RoutePrefix("reviews")]
public class ReviewsController : Controller
{
// 匹配: /spotlight-review
[Route("~/spotlight-review")]
public ActionResult ShowSpotlight() { ... }
...
}
4、默认路由
我们除了可以在 Action 上使用[Route]外,也可以用在 Controller 上,当[Route]用在 Controller 上时,它就定义了一个默认路由规则,它会对这个 Controller 下的所有 Action 起作用,除非某个 Action 上也应用了 [Route] 特性覆盖了 Controller 上的[Route]。但要注意的是应用在 Controller 上的 [Route] 一定要加上 {action},否则会抛出“RouteData 必须包含名为'action'且值为非空字符串的项。”错误。应用在 Action 上的 [Route] 则不用加,因为 {action} 就是当前 Action。
[RoutePrefix("promotions")]
[Route("{action=index}")]
//上面定义了默认路由,并且{action}的默认值为"index",
//也就是说 URL 不包含 {action} 时,默认调用的 Action 是 Index。
public class ReviewsController : Controller
{
// 匹配: /promotions
public ActionResult Index() { ... }
// 匹配: /promotions/archive
public ActionResult Archive() { ... }
// 匹配: /promotions/new
public ActionResult New() { ... }
// 匹配: /promotions/edit/5
// 这里覆盖了默认路由规则
// 按照默认路由,这里应该匹配:/promotions/editProduct?promoId=5
[Route("edit/{promoId:int}")]
public ActionResult EditProduct(int promoId) { ... }
}
5、路由约束
路由约束可以让你指定参数的类型以及范围等,格式为:{参数:约束},举例如下:
// 匹配: /users/5
[Route("users/{id:int}"]
// 这里约束了参数“id”必须为整数类型
public ActionResult GetUserById(int id) { ... }
下面是支持的路由约束列表:
alpha,必须为大小写字母(a-z,A-Z),如:{x:alpha};
bool,必须为布尔值,如:{x:bool}
datetime,必须为DateTime(时间和日期)类型,如:{x:datetime}
decimal,必须为decimal类型,如:{x:decimal}
double,必须为64bit浮点数,如:{x:double}
float,必须为32bit浮点数,如:{x:float}
guid,必须为GUID,如:{x:guid}
int,必须为32bit整数,如:{x:int}
length,字符串长度必须为指定值或者在指定范围内,如:{x:length(6)} {x:length(1,20)}
long,必须为64bit整数,如:{x:long}
max,小于等于指定值的整数,如:{x:max(10)}
maxlength,字符串长度小于等于指定值,如:{x:maxlength(10)}
min,大于等于指定值的整数整数,如:{x:min(10)}
minlength,字符串长度大于等于指定值,如:{x:minlength(10)}
range,必须是给定范围内的整数,如:{x:range(10,50)}
regex,必须与正则表达式匹配,如:{x:(^\d{3}-\d{3}-\d{4}$)}
你可以在一个参数后面应用多个约束,用冒号分隔它们,如下:
// 匹配: /users/5
// 但是不匹配 /users/10000000000 因为id的值已经超过了int.MaxValue,
// 也不匹配 /users/0 因为后面有个min(1)约束,id 的值必须大于等于 1.
[Route("users/{id:int:min(1)}")]
public ActionResult GetUserById(int id) { ... }
值得注意的是加在可选参数上的约束,例如:
// 匹配: /greetings/bye
// 也匹配 /greetings 因为message是可选参数,
// 但是不匹配 /greetings/see-you-tomorrow 因为有maxlength(3)约束.
[Route("greetings/{message:maxlength(3)?}")]
public ActionResult Greet(string message) { ... }
6、自定义路由约束
我们可以通过实现 IRouteConstraint 接口来自定义路由约束。下面的例子展示如何自定义路由约束:
public class ValuesConstraint : IRouteConstraint
{
private readonly string[] validOptions;
public ValuesConstraint(string options)
{
validOptions = options.Split('|');
}
public bool Match(HttpContextBase httpContext, Route route,
string parameterName, RouteValueDictionary values,
RouteDirection routeDirection)
{
object value;
if (values.TryGetValue(parameterName, out value) && value != null)
{
return validOptions.Contains(value.ToString(), StringComparer.OrdinalIgnoreCase);
}
return false;
}
}
下面的代码是显示如何注册自定义的路由约束
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
var constraintsResolver = new DefaultInlineConstraintResolver();
constraintsResolver.ConstraintMap.Add("values", typeof(ValuesConstraint));
routes.MapMvcAttributeRoutes(constraintsResolver);
}
}
现在我们就可以在代码中使用这些自定义的路由约束了:
public class TemperatureController : Controller
{
// 匹配 temp/celsius 以及 /temp/fahrenheit 但不匹配 /temp/kelvin
[Route("temp/{scale:values(celsius|fahrenheit)}")]
public ActionResult Show(string scale)
{
return Content("scale is " + scale);
}
}
7、路由名称
你可以为路由规则指定一个名称,以方便生成相应的URL,举例如下:
[Route("menu", Name = "mainmenu")]
public ActionResult MainMenu() { ... }
你可以使用 Url.RouteUrl 来生成相应的 URL:
<a href="@Url.RouteUrl("mainmenu")">Main menu</a>
8、Area
ASP.NET MVC 的 Area 概念对组织大型Web应用程序很有帮助,在Attribute路由中当然少不了对它的支持,只要使用 [RouteArea],就可以把 Controller 归属到某一个 Area 下,这时你可以放心的删除 Area 下的 AreaRegistration 类了:
[RouteArea("Admin")]
[RoutePrefix("menu")]
[Route("{action}")]
public class MenuController : Controller
{
// 匹配: /admin/menu/login
public ActionResult Login() { ... }
// 匹配: /admin/menu/show-options
[Route("show-options")]
public ActionResult Options() { ... }
// 匹配: /stats
[Route("~/stats")]
public ActionResult Stats() { ... }
}
现在你可以和以往的版本一样使用 "Admin" Area,下面的代码会生成 URL "/Admin/menu/show-options":
Url.Action("Options", "Menu", new { Area = "Admin" })
你还可以通过 AreaPrefix 来设置 Area 前缀,例如:
[RouteArea("BackOffice", AreaPrefix = "back-office")]
如果你同时使用 Attribute、AreaRegistration 类这两种方式来注册 Area 的话,你应该在注册 Attribute 路由和传统路由映射之间使用 AreaRegistration 注册 Area,原因很简单,路由注册顺序必须是从最精确的匹配规则开始再到普通的匹配规则,最后才是模糊的匹配规则,这样就避免了在进行路由匹配时,过早的匹配了模糊规则,而相对精确的匹配起不到任何作用。下面的例子展示了这一点:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
AreaRegistration.RegisterAllAreas();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
转自:https://blog.csdn.net/cauchy8389/article/details/22937189
ASP.NET MVC5 :Attribute路由使用详解的更多相关文章
- ASP.NET MVC5 新特性:Attribute路由使用详解 (转载)
1.什么是Attribute路由?怎么样启用Attribute路由? 微软在 ASP.NET MVC5 中引入了一种新型路由:Attribute路由,顾名思义,Attribute路由是通过Attrib ...
- ASP.NET MVC5 新特性:Attribute路由使用详解
1.什么是Attribute路由?怎么样启用Attribute路由? 微软在 ASP.NET MVC5 中引入了一种新型路由:Attribute路由,顾名思义,Attribute路由是通过Attrib ...
- ASP.NET MVC5基础-控制器(Controller)详解
在上文ASP.NET MVC5基础 – MVC文件架构中我们简单了解了下控制器Controller的作用,本文我将详细介绍控制器Controller的使用方法. Controller的运行过程 上文我 ...
- ASP.NET MVC5基础-过滤器(Filters)详解
什么是过滤器? 过滤器的类型与作用 定义过滤器 授权过滤器 动作过滤器 结果过滤器 异常处理过滤器 过滤器的使用方法 总结 什么是过滤器? 通过上一篇关于Controller控制器的文章我们知道,MV ...
- ASP.NET MVC5基础 - Global.asax详解
简介 作用 Global.asax的处理事件 实例说明 总结 简介 Global.asax是一个文本文件,它提供全局可用代码.这些代码包括应用程序的事件处理程序以及会话事件.方法和静态变量.有时该文件 ...
- asp.net iis URLRewrite 实现方法详解
原文 asp.net iis URLRewrite 实现方法详解 实现非常简单首先你要在你的项目里引用两个dll:actionlessform.dll.urlrewriter.dll,真正实现重写的是 ...
- Admin注册和路由分发详解
Admin注册和路由分发详解 1.启动 #autodiscover_modules('admin', register_to=site) 2.注册 1.单例对象 admin.site = AdminS ...
- Asp.net中web.config配置文件详解(一)
本文摘自Asp.net中web.config配置文件详解 web.config是一个XML文件,用来储存Asp.NET Web应用程序的配置信息,包括数据库连接字符.身份安全验证等,可以出现在Asp. ...
- NUnit的Attribute使用详解
NUNIT使用详解(一) 2008/08/26 11:40 NUnit是一个单元测试框架,专门针对于.NET来写的,它是是xUnit的一员.NUnit完全由C#语言来编写,并且编写时充分利用了许多.N ...
随机推荐
- java反射意义
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制. ...
- C#编程中,在页面上如何弹出确认删除对话框
对于页面完成一个操作后,弹出一个对话框提示是否“操作成功”.举例如下:Response.Write("<script>alert('删除成功!')</script>& ...
- AIX下sort命令简介及使用
AIX下sort命令简介及使用 sort -rn +3 , r倒排序,n按照数字排序: +3按照第四列排序: 第一列是+0: 学习:http://blog.csdn.net/chen_linbo/a ...
- Linux 查看负载
top iostat -x 1 10 free uptime cat /proc/cpuinfo cat /proc/meminfo src lsof 1,查看磁盘 df -h 2,查看内存大小 f ...
- 【POJ 3700】 Missile Defence System
[题目链接] http://poj.org/problem?id=3700 [算法] 对于每一枚导弹,有4种决策 : 1.新建一套递增的系统拦截它 2.新建一套递减的系统拦截它 3.在已经建好的递增拦 ...
- javascript设计模式-继承
javascript继承分为两种:类式继承(原型链.extend函数).原型式继承(对继承而来的成员的读和写的不对等性.clone函数). 类式继承-->prototype继承: functio ...
- LeetCode.888-公平的糖果交换(Fair Candy Swap)
这是悦乐书的第339次更新,第363篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第208题(顺位题号是888).Alice和Bob有不同大小的糖果棒:A[i]是Alic ...
- cloudfoundry-----------service servicebroker 转载
目前,CloudFoundry已经集成了很多第三方的中间件服务,并且提供了用户添加自定义服务的接口.随着Cloud Foundry的发展,开发者势必会将更多的服务集成进Cloud Foundry,以供 ...
- rsync文件备份同步
1.rsync有两种认证协议: ssh认证协议 rsync server端不需要启动daemon进程,所以不用配置/etc/rsyncd.conf,只需要获取远程host的用户名密码 例: rsync ...
- [XJOI]noip40 T2统计方案
统计方案 小B写了一个程序,随机生成了n个正整数,分别是a[1]..a[n],他取出了其中一些数,并把它们乘起来之后模p,得到了余数c.但是没过多久,小B就忘记他选了哪些数,他想把所有可能的取数方案都 ...