WebApi 路由机制剖析:你准备好了吗?

时间:2021-12-14 03:55:39

前言:从MVC到WebApi,路由机制一直是伴随着这些技术的一个重要组成部分。

它可以很简单:如果你仅仅只需要会用一些简单的路由,如/Home/Index,那么你只需要配置一个默认路由就能简单搞定;

它可以很神秘:你的url可以千变万化,看到一些看似“无厘头”的url,感觉很难理解它如何找到匹配的action,例如/api/user/1/detail,这样一个url可以让你纠结半天。

它可以很晦涩:当面试官提问“请简单分析下MVC路由机制的原理”,你可能事先就准备好了答案,然后噼里啪啦一顿(型如:UrlRoutingModule→Routes→RouteData→RequestContext→Controller),你可能回答很流利,但并不一定能理解这些个对象到底是啥意思。两年前的面试,博主也这样做过。

博主觉得,究竟路由机制在你的印象中处于哪一面,完全取决于你的求知欲。路由机制博大精深,博主并未完全理解,但博主是一个好奇心重的人,总觉得神秘的东西就得探索个究竟。今天,博主根据自己的理解,分享下WebApi里面路由的原理以及使用,如有考虑不周,欢迎园友们指正。

WebApi系列文章

一、MVC和WebApi路由机制比较 1、MVC里面的路由

在MVC里面,默认路由机制是通过url路径去匹配对应的action方法,比如/Home/GetUser这个url,就表示匹配Home这个Controller下面的GetUser方法,这个很好理解,因为在MVC里面定义了一个默认路由,在App_Start文件夹下面有一个RouteConfig.cs文件

WebApi 路由机制剖析:你准备好了吗?

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 = "Department", action = "Index", id = UrlParameter.Optional } ); } }

url: "{controller}/{action}/{id}"这个定义了我们url的规则,{controller}/{action}定义了路由的必须参数,{id}是可选参数

2、WebApi里面的路由

和MVC里面的路由有点不同,WebApi的默认路由是通过http的方法(get/post/put/delete)去匹配对应的action,也就是说webapi的默认路由并不需要指定action的名称。还是来看看它的默认路由配置,我们新建一个Webapi项目,在App_Start文件夹下面自动生成一个WebApiConfig.cs文件:

WebApi 路由机制剖析:你准备好了吗?

public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API 路由 config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } }

和MVC类似,routeTemplate: "api/{controller}/{id}"这个定义了路由的模板,api/{controller}是必选参数,{id}是可选参数,那么问题就来了,如果我们的url不包含action的名称,那么如何找到请求的方法呢?我们先来简单看一个例子:

public class OrderController : ApiController { [HttpGet] public object GetAll() { return "Success"; } }

我们通过url来访问

WebApi 路由机制剖析:你准备好了吗?

说明请求能够成功。

为什么这个请求能够成功呢?那是因为,当我们访问:21528/api/Order这个路径的时候,webapi的路由引擎会自动去匹配"api/{controller}/{id}"这个模板,于是找到了控制器是Order这个,那么问题来了?它是如何定位到GetAll()这个方法的呢?这里就是和MVC不同的地方,前面说过,Webapi的路由规则是通过http方法去匹配对应的action,那么,我们通过浏览器访问:21528/api/Order这个路径的时候,浏览器默认通过url访问的都是get请求,于是webapi的路由引擎就会去找Order这个控制器里面的get请求的方法,由于没有参数,所以自动匹配到了无参数的get请求→GetAll()方法,所以请求成功!