在ASP.NET MVC中使用正则表达式定义路由(翻的)
2009-03-19 20:20
681 查看
原文地址:Defining Routes using Regular Expressions in ASP.NET MVC
貌似是很老很老的帖子,最近要用正则弄路由,顺手翻了。
把玩一阵ASP.NET MVC Framework beta2之后,我对路由功能感觉比较失望。现在是用一个请求字符串设置一条路由信息, 映射为Controller, Action, 以及Action所需要的参数。在大多数情况下工作起来没有问题,但是在比较复杂的情况下让人比较郁闷。
Scott Guthrie曾经在他的帖子中回答了他们为什么不使用正则表达式来定义路由信息,声称因为大多数人不会用,不过他承诺以后可能会作为一个备选方案,但是既然我们可以实现的话,为啥要等呢?这是我的RegexRoute类,很快很丑陋:
顺便说一下,把路由使用正则表达式的方式定义,给我们带来了很爽的“副作用”,允许我们执行验证,比如某种并不必要的约束。
上面的路由把请求分隔成两部分,一部分通过ssn选择书籍,另一部分用于通过书名搜索,我想演示使用正则表达式的灵活性,上面的代码中像这样的url请求“mysite.com/Books/Last+Argument+Of+Kings”和“mysite.com/Books/0575077905”都可以用过这个路由映射信息找到相应的action:Find(),像这样定义:
虽然可以使用正则,我对路由仍然不是100%满意,它不允许我重载controll action(现在的版本可以了),上面的示例中,我宁愿弄2个不同的查找方法:Find(string query)和Find(int ssn),通过路由信息分析请求之后调用不同的action,但是MvcRouteHandler却不知道怎么解决这个问题,只晓得抛异常。
貌似是很老很老的帖子,最近要用正则弄路由,顺手翻了。
把玩一阵ASP.NET MVC Framework beta2之后,我对路由功能感觉比较失望。现在是用一个请求字符串设置一条路由信息, 映射为Controller, Action, 以及Action所需要的参数。在大多数情况下工作起来没有问题,但是在比较复杂的情况下让人比较郁闷。
Scott Guthrie曾经在他的帖子中回答了他们为什么不使用正则表达式来定义路由信息,声称因为大多数人不会用,不过他承诺以后可能会作为一个备选方案,但是既然我们可以实现的话,为啥要等呢?这是我的RegexRoute类,很快很丑陋:
public class RegexRoute : Route { private readonly Regex _urlRegex; public RegexRoute(string urlPattern, IRouteHandler routeHandler) : this(urlPattern, null, routeHandler) { } public RegexRoute(string urlPattern, RouteValueDictionary defaults, IRouteHandler routeHandler) : base(null, defaults, routeHandler) { _urlRegex = new Regex(urlPattern, RegexOptions.Compiled); } public override RouteData GetRouteData(HttpContextBase httpContext) { string requestUrl = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2) + httpContext.Request.PathInfo; Match match = _urlRegex.Match(requestUrl); RouteData data = null; if (match.Success) { data = new RouteData(this, RouteHandler); // add defaults first if (null != Defaults) { foreach (var def in Defaults) { data.Values[def.Key] = def.Value; } } // iterate matching groups for (int i = 1; i < match.Groups.Count; i++) { Group group = match.Groups[i]; if (group.Success) { string key = _urlRegex.GroupNameFromNumber(i); if (!String.IsNullOrEmpty(key) && !Char.IsNumber(key, 0)) // only consider named groups { data.Values[key] = group.Value; } } } } return data; } }
顺便说一下,把路由使用正则表达式的方式定义,给我们带来了很爽的“副作用”,允许我们执行验证,比如某种并不必要的约束。
routes.Add(new RegexRoute(@"^Books/((?<ssn>[\d]{3}(-?)[\d]{2}\1[\d]{4})|(?<query>.+)?)$", new MvcRouteHandler()) { Defaults = new RouteValueDictionary(new { controller = "Book", action = "Find" }) });
上面的路由把请求分隔成两部分,一部分通过ssn选择书籍,另一部分用于通过书名搜索,我想演示使用正则表达式的灵活性,上面的代码中像这样的url请求“mysite.com/Books/Last+Argument+Of+Kings”和“mysite.com/Books/0575077905”都可以用过这个路由映射信息找到相应的action:Find(),像这样定义:
public class BookController : Controller { public void Find(string query, int? ssn) { // ... gets the book by ssn if present, otherwise searches using the query } }
虽然可以使用正则,我对路由仍然不是100%满意,它不允许我重载controll action(现在的版本可以了),上面的示例中,我宁愿弄2个不同的查找方法:Find(string query)和Find(int ssn),通过路由信息分析请求之后调用不同的action,但是MvcRouteHandler却不知道怎么解决这个问题,只晓得抛异常。
相关文章推荐
- 约束路由 用正则表达式约束路由 Constraining a Route Using a Regular Expression 精通ASP-NET-MVC-5-弗瑞曼
- asp.net mvc 3.0 动态无损图片压缩,及路由定义
- ASP.NET MVC - Area的路由映射(使用NampSpace)
- angular.js的路由和模板在asp.net mvc 中的使用
- ASP.NET MVC - Area的路由映射(使用NampSpace)
- 使用Route Prefix 使用属性路由 精通ASP-NET-MVC-5-弗瑞曼
- 认识 ASP.NET 3.5 MVC 路由 在WebForm项目中使用路由
- angular.js的路由和模板在asp.net mvc 中的使用
- 初识ASP.NET 3.5 MVC 路由 在WebForm项目中使用路由
- ASP.NET MVC 5 (六-2) 使用Razor表达式
- Asp.net的正则表达式使用高级技巧
- 005. Asp.Net Routing与MVC 之三: 路由在MVC的使用
- asp.net服务端使用正则表达式验证数据合法性.
- ASP.NET MVC 3 Validation - 正则表达式验证RegularExpressionAttribute之日期验证
- 运用路由约束 使用属性路由 精通ASP-NET-MVC-5-弗瑞曼
- 【转】【Asp.Net MVC】asp.net mvc Model验证总结及常用正则表达式
- 填充区域 (Populating an Area) | 使用区域 | 高级路由特性 | 精通ASP-NET-MVC-5-弗瑞曼
- asp.net web form 使用URL路由 注不是mvc中的路由
- 在ASP.NET MVC中使用WebApi注册路由注意事项