今天复习一下WebAPI的路由知识:
首先分析一下MVC路由和WebAPI路由的区别:
在mvc里,默认的路由机制是通过URL路径去匹配控制器和Action方法的,在mvc中的默认路由定义在App_Start文件夹下的RouteConfig.cs文件下:
public class RouteConfig{public static void RegisterRoutes(RouteCollection routes){routes.IgnoreRoute("{resource}.axd/{*pathInfo}");routes.MapRoute(name: "Default",url: "{controller}/{action}/{id}",defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });}}
在webapi里,默认的路由机制是通过URL路径去匹配控制器,然后通过http的方法去匹配Action的,在WebAPI中的默认路由定义在App_Start文件夹下的WebApiConfig.cs文件下:
public static class WebApiConfig{public static void Register(HttpConfiguration config){// Web API 配置和服务// Web API 路由config.MapHttpAttributeRoutes();config.Routes.MapHttpRoute(name: "RestFulApi",routeTemplate: "api/{controller}/{id}",defaults: new { id = RouteParameter.Optional });}}
WebApi的路由基础:
将MapHttpRoute方法转定义有4个重载的方法:
//// 摘要:// 映射指定的路由模板。//// 参数:// routes:// 应用程序的路由的集合。//// name:// 要映射的路由的名称。//// routeTemplate:// 路由的路由模板。//// 返回结果:// 对映射路由的引用。public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate);//// 摘要:// 映射指定的路由模板并设置默认路由值。//// 参数:// routes:// 应用程序的路由的集合。//// name:// 要映射的路由的名称。//// routeTemplate:// 路由的路由模板。//// defaults:// 一个包含默认路由值的对象。//// 返回结果:// 对映射路由的引用。public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults);//// 摘要:// 映射指定的路由模板并设置默认路由值和约束。//// 参数:// routes:// 应用程序的路由的集合。//// name:// 要映射的路由的名称。//// routeTemplate:// 路由的路由模板。//// defaults:// 一个包含默认路由值的对象。//// constraints:// 一组表达式,用于指定 routeTemplate 的值。//// 返回结果:// 对映射路由的引用。public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, object constraints);//// 摘要:// 映射指定的路由模板并设置默认的路由值、约束和终结点消息处理程序。//// 参数:// routes:// 应用程序的路由的集合。//// name:// 要映射的路由的名称。//// routeTemplate:// 路由的路由模板。//// defaults:// 一个包含默认路由值的对象。//// constraints:// 一组表达式,用于指定 routeTemplate 的值。//// handler:// 请求将被调度到的处理程序。//// 返回结果:// 对映射路由的引用。public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, object constraints, HttpMessageHandler handler);
看看每个参数的作用:
name:表明路由的名称,注册多个路由时保证不重复就行;
routeTemplate:路由匹配规则。默认是“api/{controller}/{id}”,前面的api是用来区分mvc路由的,不是必选项,是可变的,{controller}是控制器的占位符,{id}是形参的占位符;
defaults:一个包含默认路由值的对象,可以设置controller的默认值;
constraints:对形参的约束;
注册的路由是按照注册先后的顺序进行匹配的,注册越靠前,优先级越大
我们知道,WebApi是符合RESTful风格的,那么如果在一个控制器内部,我们需要提供多个相同的http方法,相同参数的接口我们应该怎么解决呢?
1:活用[Route("")]
在相同请求方法的action的前面可以加上[Route]路由特性进行区分:
/// <summary> /// 这里可以通过http://localhost:xxxx/api/Values对这个action进行访问 /// </summary> /// <returns></returns> public IEnumerable<string> Get1() { return new string[] { "value1", "value2" }; } /// <summary> /// 这里可以通过http://localhost:xxxx/apis/Values/qqqqq对这个action进行访问 /// </summary> /// <returns></returns> [Route("apis/Values/qqqqq")] public IEnumerable<string> Get2() { return new string[] { "value3", "value4" }; }
和朋友聊了一下,发现这个做法本身就和RESTful风格相抵触,所以就不深究了,一般是对action进行重载,而不是在这上面想办法。