深入探讨Web API路由约束

Web API开发中,路由约束是控制HTTP请求如何映射到控制器动作的重要机制。本文将详细介绍路由约束的概念、不同类型的约束,并指导如何创建自定义路由约束。

什么是路由约束?

路由约束是Web API中用于限制URL参数的机制,它确保传入的URL参数符合特定的格式或条件。在讨论路由约束之前,先简要了解属性路由。属性路由是Web API2中引入的一种路由方式,它允许开发者通过属性来定义路由模板。

属性路由允许开发者定义路由模板,从而实现资源的层次结构管理。以下是一个简单的示例代码:

public IEnumerable<ServerData> GetServerData(int type) { return ServerDataRepository.GetAll().Where(d => d.Type == type); }

通过这种方式,可以轻松定义URI模式并管理资源。

假设有一个复杂的URI,其中参数可以是任何类型(如int或string)。以下是一个示例代码:

public IEnumerable<DataDetail> GetDataDetailsByType(int type) { // some stuff here }

当请求到来时,Web API会尝试匹配定义在路由模板中的URI。可以传递不同的值来使这个模板有效:

  • http://127.0.0.1/serverdata/external/datadetails
  • http://127.0.0.1/serverdata/1/datadetails
  • http://127.0.0.1/serverdata/1oT/datadetails

在这个URI路由模板中,{type}是一个参数(通常称之为URI占位符),当传递值时,它会自动分配给动作方法的参数。

路由约束的工作原理

在上述URI路由模板中,{type}是一个参数,当传递"external"时,模板匹配成功,但实际上参数是int类型。这里的问题显而易见:需要一种机制来限制参数,以确保Web API匹配正确的URI路由模板。这就是路由约束的作用。

以下是一些常用的路由约束:

  • int约束:限制为32位整数值
  • double约束:限制为64位浮点值
  • float约束:限制为32位浮点值
  • guid约束:限制为GUID值
  • length约束:限制字符串到指定长度或指定长度范围
  • long约束:限制为64位整数值
  • alpha约束:限制为大小写英文字母
  • bool约束:限制为布尔值(true/false)
  • datetime约束:限制为DateTime值
  • decimal约束:限制为十进制值
  • range约束:限制整数在一定范围内

除了上述约束,还有一些其他约束,如regex、maxlength、minlength等,这些约束的名称已经很清楚地说明了它们的用途。

创建自定义路由约束

虽然有很多内置的路由约束可用,但在某些场景下,可能需要一些特殊的约束。为了满足这些需求,可以创建自定义约束。

创建自定义路由约束的第一步是实现IHttpRouteConstraint接口。以下是一个示例代码,展示了如何创建一个限制不良词汇的自定义约束:

public class NoBadWordsConstraint : IHttpRouteConstraint { public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary<string, object> values, HttpRouteDirection routeDirection) { object value; string[] badWords = new string[] { "bad1", "bad2", "bad3" }; if (values.TryGetValue(parameterName, out value) && value != null) { string stringValue; if (value is string) { stringValue = (string)value; foreach (var w in badWords) { if (w.Contains(stringValue)) return false; } return true; } } return false; } }

要使用这个自定义约束,需要先在WebApiConfig类中的Register方法中注册它:

var defaultconstraintResolver = new DefaultInlineConstraintResolver(); defaultconstraintResolver.ConstraintMap.Add("nobadword", typeof(NoBadWordsConstraint)); config.MapHttpAttributeRoutes(defaultconstraintResolver); [Route("serverdata/{word:length(10)}")] public IEnumerable<EmployeeData> GetEmployeebyword(string word) { // some stuff here }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485