C# 路线及;消息处理程序:请求处理顺序问题

C# 路线及;消息处理程序:请求处理顺序问题,c#,asp.net,asp.net-web-api,C#,Asp.net,Asp.net Web Api,我面临ASP.NET Web API请求管道的执行顺序问题 根据ASP.NET Web API文档(可用),全局消息处理程序应该在路由机制之前执行 在此图像上,MessageHandler1是一个全局消息处理程序,而MessageHandler2特定于路由2 我创建了一个非常简单的示例来说明执行顺序中似乎存在问题……或者我确实遗漏了一些重要的内容 我有这个控制器 public class FooController : ApiController { [HttpPut] pu

我面临ASP.NET Web API请求管道的执行顺序问题

根据ASP.NET Web API文档(可用),全局消息处理程序应该在路由机制之前执行

在此图像上,
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() }
    );
}
simpleMethodOrrideHandler
是一个非常简单的
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
时,程序首先进入
HttpPutOnlyConstraint
Match
方法,这是错误的

如果我们参考前面链接的图像,那么消息处理程序应该首先执行,不幸的是,它不是

因此,当然,
Match
返回
false
并且没有为请求找到控制器/操作,404发生

如果我从路由定义中删除约束,程序将进入
SimpleMethodOverrideHandler
,请求的方法将成功更改,并且它能够匹配并执行控制器的方法

我做错什么了吗?要执行这些操作,是否需要知道一个秘密配置参数?:-)

如果有人需要整个项目,它是可用的


谢谢。

您混淆了路由引擎和Web API管道
HttpRoutingDispatcher
不是路由引擎概念。将首先处理路由约束,因为基础主机需要构建路由表并匹配您请求的路由


HttpRoutingDispatcher
只是
HttpMessageHandler
的另一个实现,它所做的只是检查已匹配路由的
IHttpRoute
,并选择下一步调用哪个消息处理程序。如果没有每个路由处理程序,它会将处理委托给
HttpControllerDispatcher

我对此了解不够,无法发布答案,但我认为您可以查看RouteMagic的源代码(位于)。它使用一个动态注册的处理程序来拦截路由,但也有一些其他路由功能,您可以从中获得灵感。
public class HttpPutOnlyConstraint : IHttpRouteConstraint {
    public bool Match( HttpRequestMessage request,
                       IHttpRoute route,
                       string parameterName,
                       IDictionary<string, object> values,
                       HttpRouteDirection routeDirection ) {
        return request.Method == HttpMethod.Put;
    }
}