问题
在此解释一下,空气路由,是本人臆想出来,觉着更能表达 IgnoreRoute 的意图,如果看着辣眼睛^^,请见谅。
我们在之定义过集中式路由,集中式路由有一个特点就是短路,但是现在我们不想让某些路由工作(匹配并由路由引擎处理请求)。那么我们应该怎么办呢?
解决方案其实思路很简单,就是想把某些路由忽略了。ASP.NET WEB API 提供了一个叫做的 StopRoutingHandler 的处理器,简单说,他就是一个消息处理器,可以通过他来强制指定的路由被忽略掉。他是 System.Web.Http 的一部分,从 Web API 2.1 开始被引入的。StopRoutingHandler 处理器作用在指定路由上的表现就是,强制 HttpRouteDispatcher 把该路由当成空气。
注意 ASP.NET MVC 有自己把版本的StopRoutingHandler(位于 Systme.Web)。如果 ASP.NET WEB API 运行在一个完全的 ASP.NET 运行时之上,同时有权限访问 System.Web 的话,那么,一样会对 ASP.NET WEB API 起作用。
工作原理ASP.NET WEB API 会匹配所有他能够的匹配到的请求,如果发现那些路由的被忽略的,他就不会去处理他。这也可能是一个对静态文件的请求,这样的请求必须有服务器层面来处理,或者说,如果运行了一个 OWIN 管道,他是需要被指定的 OWIN 中间件调用处理的。
注意 OWIN 中间件是顺序处理的,如果 在 OWIN 管道最开始就注册了ASP.NET WEB API,通常是需要在 ASP.NET WEB API 路由的合适位置做忽略处理。
HttpRoutingDispatcher 已经在上一篇 [水煮 ASP.NET Web API2 方法论](3-8)怎样给指定路由配置处理器
中提到,他是专门的消息处理器,,他的职责是检查路由的 IHttpRoute 是不是匹配当前请求,同时,委托处理程序处理 HttpControllerDispatcher。HttpRoutingDispatcher 是通过 Http Server 调用的。
HttpRoutingDispatcher 会检查路由是否有处理器,如果有的话,会继续检查是否是 StopRoutingHandler 类型的,如果也是的话,那么这个请求就会被路由引擎当作空气。这个逻辑是是通过 ASP.NET WEB API 的源代码推断出来的,如代码片段 3-25 所示。
代码片段 3-25. 从 ASP.NET WEB API 源码中摘取的一部分,展示了如何使用 StopRoutingHandler 以及如何成空气的。
1 protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken 2 cancellationToken) 3 { 4 IHttpRouteData routeData = request.GetRouteData(); 5 if (routeData == null) 6 { 7 routeData = _configuration.Routes.GetRouteData(request); 8 if (routeData != null) 9 { 10 request.SetRouteData(routeData); 11 } 12 } 13 if (routeData == null || (routeData.Route != null && routeData.Route.Handler is 14 StopRoutingHandler)) 15 { 16 request.Properties.Add(HttpPropertyKeys.NoRouteMatched, true); 17 return Task.FromResult(request.CreateErrorResponse( 18 HttpStatusCode.NotFound, 19 Error.Format(SRResources.ResourceNotFound, request.RequestUri), 20 SRResources.NoRouteData)); 21 } 22 routeData.RemoveOptionalRoutingParameters(); 23 var invoker = (routeData.Route == null || routeData.Route.Handler == null) 24 ? _defaultInvoker 25 : new HttpMessageInvoker(routeData.Route.Handler, disposeHandler: false); 26 return invoker.SendAsync(request, cancellationToken); 27 }
代码演示为了在 ASP.NET WEB API 中配置空气路由,可以使用来个两种语法结果(让我想起,骆驼祥子中,“回”字的几种写法)。
代码片段 3-26. 显示的使用 StopRoutingHandler 来设置空气路由。
config.Routes.MapHttpRoute( name: "Content", routeTemplate: "content/{*params}", defaults: null, constraints: null, handler: new StopRoutingHandler()); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "{controller}/{id}", defaults: new {id = RouteParameter.Optional} );
代码片段 3-27. 通过扩展方法 IgnoreRoute 设置空气路由。