asp.netasp.netAsp.net开发

ASP.NET WEB API 之属性路由

2017-01-17  本文已影响237人  三只仓鼠

以下为常规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错误。)

Paste_Image.png

通常情况下,在同一个控制器中的所有路由以相同的前缀开头

    [Route("api/books")]
    [Route("api/books/{id:int}")]
    [Route("api/books")]

这样很明显是比较麻烦的。所以我们用[RoutePrefix]属性来设置一个公共的前缀

Paste_Image.png

测试结果

Paste_Image.png

如果使用了[RoutePrefix]的话,某些比较特殊的api,我们可以使用波浪线来重写路由前缀,如下:

Paste_Image.png

测试结果(同一个类下)


Paste_Image.png

路由前缀中也可以包含参数,如下

Paste_Image.png

测试结果

Paste_Image.png

可以在路由中添加参数约束,如下

Paste_Image.png

测试结果

Paste_Image.png

如果参数不是Int类型,则不会匹配到该路由
以下都是一些会被支持到的约束

Paste_Image.png

可以使用多个约束,但是要用冒号分开

[Route("users/{id:int:length(1,3)}")]
public User GetUserById(int id) { ... }

结果

Paste_Image.png

如果不在范围内的话则匹配不到

Paste_Image.png

自定义路由约束,需要实现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) { ... }
}

差不多写这么多常用的,剩余部分自己查看官网!

上一篇下一篇

猜你喜欢

热点阅读