我遇到了ASP.NET Web API請求管道的執行順序問題。路由和消息處理程序:請求處理訂單問題
根據ASP.NET Web API文檔(可用here),全局消息處理程序應該在路由機制之前執行。
在該圖像中,MessageHandler1
是一個全球性的消息處理程序而MessageHandler2
是特定於路線2。
我創建了一個非常簡單的例子來說明在執行順序中似乎存在問題......或者我真的錯過了一些重要的東西。
我有這個控制器
public class FooController : ApiController {
[HttpPut]
public string PutMe() {
return Request.Method.Method;
}
}
它只接受PUT
請求。
該應用程序被配置爲這樣:
protected void Application_Start() {
var configuration = GlobalConfiguration.Configuration;
configuration.MessageHandlers.Add(new SimpleMethodOverrideHandler());
configuration.Configuration.Routes.MapHttpRoute(
name: "Foo",
routeTemplate: "api/foo",
defaults: new { controller = "foo", action = "putme" },
constraints: new { put = new HttpPutOnlyConstraint() }
);
}
SimpleMethodOverrideHandler
是一個非常簡單的DelegatingHandler
,只是根據在所述查詢串中的"method"
參數改變請求的方法。
public class SimpleMethodOverrideHandler : DelegatingHandler {
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
var method = request.RequestUri.ParseQueryString()["method"];
if(!string.IsNullOrEmpty(method)) {
request.Method = new HttpMethod(method);
}
return base.SendAsync(request, cancellationToken);
}
}
所以基本上,請求/api/foo?method=put
在我的瀏覽器會火起來FooController
的PutMe
方法。
事實上,正如前面所看到的,消息處理程序在將請求傳遞到HttpRoutingDispatched
之前處理這些請求。
最後,這裏是如何的constaint HttpPutOnlyConstraint
定義:
public class HttpPutOnlyConstraint : IHttpRouteConstraint {
public bool Match(HttpRequestMessage request,
IHttpRoute route,
string parameterName,
IDictionary<string, object> values,
HttpRouteDirection routeDirection) {
return request.Method == HttpMethod.Put;
}
}
那麼問題是,當我在我的瀏覽器內請求/api/foo?method=put
,程序首先進入HttpPutOnlyConstraint
的Match
方法,這是錯誤。
如果我們引用先前鏈接的圖像,則應該首先執行消息處理程序,但不幸的是它不是。
因此,當然,Match
返回false
並且沒有找到該請求的控制器/操作,404發生。
如果我從路徑定義中刪除約束條件,程序將進入SimpleMethodOverrideHandler
,請求的方法被成功修改,並且它能夠匹配和執行我的控制器的方法。
我做錯了什麼?有沒有一個祕密的配置參數知道爲了做這樣的事情? :-)
如果有人需要整個項目,它可用here [7KB zip file]。
謝謝。
我不太瞭解這個帖子,但認爲它可以幫助你查看RouteMagic的源代碼(https://github.com/Haacked/RouteMagic)。它使用動態註冊的處理程序來攔截路由,但也有一些其他路由功能可能會從中獲得靈感。 –