路由和放大器;消息处理程序:请求处理顺序问题 [英] Routing & message handlers: request processing order issue

查看:100
本文介绍了路由和放大器;消息处理程序:请求处理顺序问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm facing an issue with the execution order of the ASP.NET Web API request pipeline.

据的的ASP.NET Web API文档(可的这里),全球消息处理程序应该路由机制之前执行。

According to the ASP.NET Web API documentation (available here), global message handlers are supposed to be executed before the routing mechanism.

在这一形象, MessageHandler1 是一个全球性的消息处理程序,而 MessageHandler2 是特定的路线2

On this image, MessageHandler1 is a global message handler whereas MessageHandler2 is specific to Route 2.

我创建了一个非常简单的例子表明,似乎是在执行顺序的问题......或者我真的失去了一些东西很重要。

I created a very simple example to show that there seems to be an issue in the execution order… or I'm really missing something important.

我有这个控制器

public class FooController : ApiController {
    [HttpPut]
    public string PutMe() {
        return Request.Method.Method;
    }
}

它只接受 PUT 请求。

的应用程序被配置为这样:

The application is configured as such:

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 这只是改变根据请求的方法 办法参数的查询字符串。

SimpleMethodOverrideHandler is a very simple DelegatingHandler that just changed the request's method according to a "method" parameter in the query string.

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 /富?方法=把在我的浏览器会火起来的 FooController的 PutMe 方法。结果
事实上,正如前面所看到的,然后才会慢慢传递给消息处理程序对待请求 HttpRoutingDispatched

So basically, requesting /api/foo?method=put in my browser would fire up FooController's PutMe method.
Indeed, as seen earlier, the message handler treats the requests before it gets passed to the HttpRoutingDispatched.

最后,这里是如何的constaint HttpPutOnlyConstraint 的定义是:

Finally, here's how the the constaint HttpPutOnlyConstraint is defined:

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 /富?方法=把我的浏览器中,程序首先进入 HttpPutOnlyConstraint 匹配方法,这是错误的。


Well the problem is that when I request /api/foo?method=put within my browser, the program first enters HttpPutOnlyConstraint's Match method, which is wrong.

如果我们指的pviously链接的图像的$ P $,消息处理程序应该是先执行,可惜事实并非如此。

If we refer to the previously linked image, the message handler is supposed to be executed first, unfortunately it is not.

等等,当然,匹配收益并没有控制器/行为被发现的请求,404发生

So, of course, Match returns false and no controller/action is found for the request, 404 happens.

如果我从路由定义删除约束,程序进入 SimpleMethodOverrideHandler ,请求的方法被成功地改变了,这是能够匹配并执行我的控制器的方法。

If I remove the constraint from the route definition, the program enters SimpleMethodOverrideHandler, the request's method gets changed successfully and it is able to match and execute my controller's method.

我是不是做错了什么?有一个秘密的配置参数,以做出这样的事情知道吗? : - )

Am I doing something wrong? Is there a secret configuration parameter to know in order to do such things? :-)

如果有人需要整个项目,它的可用 [7KB zip文件]

If anyone needs the whole project, it's available here [7KB zip file].

感谢您。

推荐答案

您混淆路由引擎使用Web API管线。 HttpRoutingDispatcher 不是路由引擎的概念。因为你的底层主机需要建立一个路由表,并符合您的要求路由的路由约束将得到优先处理。

You are confusing routing engine with Web API pipeline. HttpRoutingDispatcher is not a routing engine concept. The route constraints will be processed first because your underlying host needs to build a route table and match the route for your request.

HttpRoutingDispatcher 简直就是另一个实施 HttpMessageHandler 和所有它是它检查 IHttpRoute 已配对,并选择下一个要调用的消息处理程序的路线。如果没有每个路由处理present,它代表了处理 HttpControllerDispatcher

HttpRoutingDispatcher is simply another implementation of HttpMessageHandler and all it does is it examines the IHttpRoute of the route that has been matched, and chooses which message handler to call next. If there is no per-route handler present, it delegates the processing to HttpControllerDispatcher.

这篇关于路由和放大器;消息处理程序:请求处理顺序问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆