博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASP.NET MVC 中的路由
阅读量:7107 次
发布时间:2019-06-28

本文共 8239 字,大约阅读时间需要 27 分钟。

普通的路由

在以前版本的ASP.NET MVC里,这些规则会被定义在RouteConfig.cs文件,也有扩展可以实现基于特性的路由,不过是收费滴,另外还有一个扩展: ,也很不错;理论上ASP.NET MVC 中要实现任意的规则URL 应该是没有问题的。

Attribute routing

ASP.NET MVC now supports , thanks to a contribution by Tim McCall, the author of . With attribute routing you can specify your routes by annotating your actions and controllers.

比如配置的酒店详情页路由

//HOTEL DETAIL            routes.MapRoute(name: "HotelDetail",                        url: "hotel/{hotelCd}",                        defaults: new { controller = "Hotel", action = "HotelDetail" },                        constraints: new { controller = "Hotel", hotelCd = @"[a-zA-Z0-9]*" }            );

自定义路由约束

如果是要精确到数据是否准确,可以自定义的路由规则,实现 IRouteConstraint 接口,重写Match方法即可。

public class CityConstraint : IRouteConstraint    {        ///         /// 匹配二级城市的URL        ///         ///         ///         ///         ///         ///         /// 
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) { try { if (values["cityName"] == null || values["cityName"].ToString().ContainsAny(new string[] { "home", "list", "hotel", "member", "activity", "ajax","alipay", "gift"})) { return false; } var city = CacheData.getCitys().Where(data => data.Pinyin.Equals(values["cityName"].ToString(), StringComparison.OrdinalIgnoreCase)).ToList(); if (city == null || city.Count == 0) { return false; } return true; } catch (Exception ex) { return false; } } routes.MapRoute( name: "HotelCity", url: "{cityName}/p{pageNo}", defaults: new { controller = "HotelSEO", action = "Hotel", pageNo = "1" }, constraints: new { cityName = new CityConstraint(), pageNo = @"\d+" } //constraints: new { cityName = @"(|shanghai|beijing|hefei|chuzhou)"} );

考虑到hotel/xxx可以匹配到酒店编号不符合规则的酒店,也可能是用户手误打错了,可以捕获所有以hotel开头不符合正则的的URL到酒店的目录页

routes.MapRoute(name: "HotelMenu",                           url: "hotel/{*values}",                           defaults: new { controller = "Menu", action = "Index" }            );

特性路由

要启用特性路由,只要项目中注册MapMvcAttributeRoutes方法

public static void RegisterRoutes(RouteCollection routes)        {            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");            //启用特性路由              routes.MapMvcAttributeRoutes();            routes.MapRoute(                name: "Default",                url: "{controller}/{action}/{id}",                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }            );        }

可选的URL参数和默认值

// eg: /hotel    // eg: /hotel/123456    [Route("hotel/{hotelCd?}")]    public ActionResult View(string hotelCd)    {        if (!String.IsNullOrEmpty(hotelCd))        {            return View("HotelDetail", GetHotelDetail(hotelCd));        }        return View("HotelMenu", GetHotelCitys());    }

路由前缀

比如现在的会员页面,都是以user 开头的如

// eg: /user    [Route("user")]    public ActionResult Index() { ... }    // eg: /user/5    [Route("user/{userId}")]    public ActionResult Show(int userId) { ... }    // eg: /user/5/edit    [Route("user/{userId}/edit")]    public ActionResult Edit(int userId) { ... }

这个时候也在控制器加一个全局[RoutePrefix]特性

[RoutePrefix("user")]public class userController : Controller{    // eg.: /user    [Route]    public ActionResult Index() { ... }    // eg.: /user/5    [Route("{userId}")]    public ActionResult Show(int userId) { ... }    // eg.: /user/5/edit    [Route("{userId}/edit")]    public ActionResult Edit(int userId) { ... }}

重写路由规则

如果有的时候需要重写路由规则,就加个波浪线 ~

[RoutePrefix("review")]public class ReviewController : Controller{    // eg.: /code-review    [Route("~/code-review")]    public ActionResult CodeView() { ... }}

也可以在controller中定义Route特性,将action作为一个参数。这个路由会被应用到controller上的所有action,除非某个action已经定义了一个[Route]特性,重写controller的默认行为。

[RoutePrefix("user")][Route("{action=Index}")]public class ReviewsController : Controller{    // eg.: /user    public ActionResult Index() { ... }     // eg.: /user/set    public ActionResult Set() { ... }     // eg.: /user/new    public ActionResult New() { ... }     // eg.: /user/edit/5    [Route("edit/{userId:int}")]    public ActionResult Edit(int promoId) { ... }}

路由约束

路由约束让你可以限制参数在路由模板里如何匹配。通常的语法是{parameter:constraint},如:

// eg: /users/5[Route("users/{id:int}"]public ActionResult GetUserById(int id) { ... }// eg: users/ken[Route("users/{name}"]public ActionResult GetUserByName(string name) { ... }

支持的约束类型:

Constraint Description Example
alpha Matches uppercase or lowercase Latin alphabet characters (a-z, A-Z) {x:alpha}
bool Matches a Boolean value. {x:bool}
datetime Matches a DateTime value. {x:datetime}
decimal Matches a decimal value. {x:decimal}
double Matches a 64-bit floating-point value. {x:double}
float Matches a 32-bit floating-point value. {x:float}
guid Matches a GUID value. {x:guid}
int Matches a 32-bit integer value. {x:int}
length Matches a string with the specified length or within a specified range of lengths. {x:length(6)}
{x:length(1,20)}
long Matches a 64-bit integer value. {x:long}
max Matches an integer with a maximum value. {x:max(10)}
maxlength Matches a string with a maximum length. {x:maxlength(10)}
min Matches an integer with a minimum value. {x:min(10)}
minlength Matches a string with a minimum length. {x:minlength(10)}
range Matches an integer within a range of values. {x:range(10,50)}
regex Matches a regular expression. {x:regex(^\d{3}-\d{3}-\d{4}$)}

可以用分号分隔,定义多个约束,如:

// eg: /users/5// but not /users/10000000000 because it is larger than int.MaxValue,// and not /users/0 because of the min(1) constraint.[Route("users/{id:int:min(1)}")]public ActionResult GetUserById(int id) { ... }

比如MS的这篇文章,大致可以配置成如下的路由规则:

[Route("/b/webdev/archive/{year:regex(\\d{4})}")]
[Route("/b/webdev/archive/{year:regex(\\d{4})}/{month:regex(\\d{1,2})}")]
[Route("/b/webdev/archive/{year:regex(\\d{4})}/{month:regex(\\d{1,2})}/{day:regex(\\d{1,2})}/{slug}")]
public ActionResult GetArchivePost(string year, string month,string day,string slug){ };

特性路由中自定义路由约束

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{    // eg: temp/celsius and /temp/fahrenheit but not /temp/kelvin    [Route("temp/{scale:values(celsius|fahrenheit)}")]    public ActionResult Show(string scale)    {        return Content("scale is " + scale);    }}

路由名称

可以给一个路由指定一个名字,以便于URL生成,如:

[Route("menu", Name = "mainmenu")]public ActionResult MainMenu() { ... }

使用@Url.RouteUrl 生成一个超链接

特性路由VS普通的路由

其实这个问题与Spring是基于xml配置好,还是注解的方式好,具体还得看使用场景,每一种方式都有自己的优势与劣势,比如基于普通的路由可以自定义直接 的一些逻辑,基于特性的路由可以快速现实一个路由的实现。

// eg: /books/lang        // eg: /books/lang/en        // eg: /books/lang/he        [Route("books/lang/{lang=en}")]        public ActionResult Lang(string lang)        {            return View();        }        [Route("~/attribute-routing-in-asp-net-mvc-5")]        public ActionResult Hotel()        {            return Content("I'am mvc attribute route! ");        }

Refer:

What's New in ASP.NET MVC 5
What’s New in ASP.NET MVC 5.2
attribute-routing-in-asp-net-mvc-5

转载地址:http://nxphl.baihongyu.com/

你可能感兴趣的文章
一些颜色工具网站
查看>>
如何在Linux下如何安装多语言包
查看>>
Web GIS离线解决方案
查看>>
利用ZABBIX的RPC-JSON作API扩展应用示例
查看>>
_awr_sql_child_limit是否能控制awr记录sql执行次数的问题
查看>>
网页设计DIV+CSS——第2 天:什么是名字空间
查看>>
使用Amoeba for mysql实现mysql读写分离
查看>>
从QQ密码修改的小问题回顾下URL Fragment
查看>>
poj 2195 Going Home
查看>>
基于Hadoop的云盘系统客户端技术难点之一 上传和下载效率优化
查看>>
JSP的运行原理
查看>>
12篇学通C#网络编程——第二篇 HTTP应用编程(上)
查看>>
手机号码注册带正则验证和发验证码倒计时
查看>>
讨喜的隔离可变性-前言
查看>>
iOS开发CoreAnimation解读之二——对CALayer的分析
查看>>
IOS UISwitch 用法总结
查看>>
使用UIWebView中html标签显示富文本
查看>>
iOS图片压缩上传
查看>>
Velocity官方指南-Velocity是如何工作的
查看>>
network block device(nbd)
查看>>