以下为常规mvc路由
config.routes.maphttproute(
name: "defaultapi",
routetemplate: "api/{controller}/{id}",
defaults: new { id = routeparameter.optional },
);
如果我们要实现类似以下效果路由的话,使用常规公约路由比较麻烦。
order/miles/三只松鼠干果/2袋
order/2017/1/13
如果使用属性路由的话就比较简单了。
新建web api项目的话,打开app_start目录下的webapiconfig.cs文件添加以下代码开启属性路由配置。
config.maphttpattributeroutes();
属性路由也可以和公约路由混合使用,如下:
public static void register(httpconfiguration config)
{
// web api 配置和服务
// web api 路由
config.maphttpattributeroutes();
config.routes.maphttproute(
name: "defaultapi",
routetemplate: "api/{controller}/{id}",
defaults: new { id = routeparameter.optional },
constraints: new { id=@"\d+"}
);
}
在要使用属性路由的方法上打上特性标记,如下 :
[route("order/{usernickname}/{productname}/{count}")]
测试结果(url经过了编码,不然会报400错误。)
通常情况下,在同一个控制器中的所有路由以相同的前缀开头
[route("api/books")]
[route("api/books/{id:int}")]
[route("api/books")]
这样很明显是比较麻烦的。所以我们用[routeprefix]属性来设置一个公共的前缀
测试结果
如果使用了[routeprefix]的话,某些比较特殊的api,我们可以使用波浪线来重写路由前缀,如下:
测试结果(同一个类下)
路由前缀中也可以包含参数,如下
测试结果
可以在路由中添加参数约束,如下
测试结果
如果参数不是int类型,则不会匹配到该路由
以下都是一些会被支持到的约束
可以使用多个约束,但是要用冒号分开
[route("users/{id:int:length(1,3)}")]
public user getuserbyid(int id) { ... }
结果
如果不在范围内的话则匹配不到
自定义路由约束,需要实现ihttprouteconstraint接口,具体查看官方
public class nonzeroconstraint : ihttprouteconstraint
{
public bool match(httprequestmessage request, ihttproute route, string parametername,
idictionary<string, object> values, httproutedirection routedirection)
{
object value;
if (values.trygetvalue(parametername, out value) && value != null)
{
long longvalue;
if (value is long)
{
longvalue = (long)value;
return longvalue != 0;
}
string valuestring = convert.tostring(value, cultureinfo.invariantculture);
if (int64.tryparse(valuestring, numberstyles.integer,
cultureinfo.invariantculture, out longvalue))
{
return longvalue != 0;
}
}
return false;
}
}
注册约束
public static class webapiconfig
{
public static void register(httpconfiguration config)
{
var constraintresolver = new defaultinlineconstraintresolver();
constraintresolver.constraintmap.add("nonzero", typeof(nonzeroconstraint));
config.maphttpattributeroutes(constraintresolver);
}
}
使用约束
[route("{id:nonzero}")]
public httpresponsemessage getnonzero(int id) { ... }
可选的uri参数和默认值
你可以通过添加一个问号标记路由参数使成为一个可选的uri参数。如果一个路由参数是可选的,你必须为这个方法参数定义一个默认值。
public class bookscontroller : apicontroller
{
[route("api/books/locale/{lcid:int?}")]
public ienumerable<book> getbooksbylocale(int lcid = 1033) { ... }
}
或者在路由模版中定义默认值
public class bookscontroller : apicontroller
{
[route("api/books/locale/{lcid=1033}")]
public ienumerable<book> getbooksbylocale(int lcid) { ... }
}
以上就是web api的 asp.net属性路由实例详解的详细内容。