未定义路由时不执行DelegatingHandlers

时间:2018-07-31 02:27:04

标签: c# asp.net-web-api asp.net-web-api2 asp.net-web-api-routing

我正在研究一个WebAPI 2项目,该项目当前仅使用基于属性的路由,以至于注册中没有定义路由,并且一切都按预期进行。

但是,我现在要添加一个DelegatingHandler来提供可通过HEAD请求ping的心跳:

public class HeartbeatMessagingHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (IsHeartbeat(request))
        {
            if (request.Method == HttpMethod.Head)
            {
                var response = new HttpResponseMessage(HttpStatusCode.NoContent) { Content = new StringContent(string.Empty) };
                var task = new TaskCompletionSource<HttpResponseMessage>();
                task.SetResult(response);
                return task.Task;
            }
        }

        return base.SendAsync(request, cancellationToken);
    }

    private static bool IsHeartbeat(HttpRequestMessage request)
    {
        return request.RequestUri.LocalPath.Equals("/Heartbeat", StringComparison.OrdinalIgnoreCase);
    }
}

但是,如果我发出了预期的HEAD http://localhost/heartbeat请求,则不会调用该处理程序;如果我调用确实存在的任何路由,则将调用处理程序;并且如果我添加了老式路由配置,则在预期的/heartbeat端点上调用处理程序。

那么,仅使用属性路由,如何处理对“虚拟”端点的请求?

更新

消息处理程序的注册方式如下:

config.MessageHandlers.Add(new HeartbeatMessagingHandler());
config.MessageHandlers.Add(new RequestAndResponseLoggerDelegatingHandler());
config.MessageHandlers.Add(new ApplicationInsightsMessageHandler());

因此它在例如我的全局日志记录处理程序,根据我的理解,消息处理程序按注册顺序接收消息。

1 个答案:

答案 0 :(得分:0)

您的处理程序很可能在管道中为时已晚,而管道中较高的处理程序则在请求到达您的处理程序之前使其短路。

考虑将您的处理程序向上插入,这样有更好的机会拦截请求

public static class WebApiConfig {
    public static void Register(HttpConfiguration config) {
        // Web API routes
        config.MapHttpAttributeRoutes();

        // add to the front of the pipeline
        config.MessageHandlers.Insert(0, new HeartbeatMessagingHandler());
    }
}