今天复习一下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]路由特性进行区分:
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进行重载,而不是在这上面想办法。