我正在研究一个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());
因此它在例如我的全局日志记录处理程序,根据我的理解,消息处理程序按注册顺序接收消息。
答案 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());
}
}