閱讀導航
在此解釋一下,空氣路由,是本人臆想出來,覺著更能表達 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 中配置空氣路由,可以使用來個兩種語法結果(讓我想起,駱駝祥子中,“回”字的幾種寫法)。
- 與上篇 [水煮 ASP.NET Web API2 方法論](3-8)怎樣給指定路由配置處理器 中的例子很像,就是在想要設置成空氣路由中的消息處理器的位置使用 StopRoutinngHandler。如代碼片段 3-26 所示。這個例子中,所有能夠匹配到 /content/* 的請求,會被 WEB API 當作空氣路由,其余的還是會被 /{controller}/{id} 定義的路由所匹配。
- 一個更簡單的方式就是使用 HttpRouteCollectionExtension 類的擴展方法 IgnoreRoute。其實內部做的是一樣的事情,在指定的路由上使用 StopRoutingHandler。如代碼片段 3-17 所示。
代碼片段 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 設置空氣路由。
config.Routes.IgnoreRoute( routeName: "Content", routeTemplate: "content/{*params}" ); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "{controller}/{id}", defaults: new {id = RouteParameter.Optional} );
文章列表