阅读导航
问题
如果仅仅针对指定的路由进行某些特定的消息处理,而不是应用于所有路由,我们应该怎么做呢?
解决方案
ASP.NET WEB API 的很多功能都内建了消息处理器。他们真正的威力是为消息的全局处理以及为全局的应用程序业务处理提供比较简单的处理机制。不过,在某一些场景下的需求是,使用消息处理器处理应用程序指定部分的特定行为。
我们要基于每个路由配置消息处理器(DelegatingHandler),而不是在 HttpConfiguration 中注册全局的。在 HttpRouteCollectionExtension 中有一个重载的 MapHttpRoute 方法 ,他是可以做到。
public static IHttpRoute(this HttpRouteCollection routes,string name,string routeTemplate,object defaults,object contraints,HttpMessageHandler handler)
注意 只能在集中式路由中使用,而不能在属性路由中使用。
工作原理
在 Web API 管道中,基于路由的消息处理器是在全局消息处理器之后,HttpControllerDispatcher 之前执行。一个叫做 HttpRouteDispatcher 的服务来负责识别给定路由是否指定了消息处理器。如果是的话,请求将交由处理器处理,否则,继续处理,匹配 Controller。
指定路由处理器需要指定 InnerHandler 来继续处理消息。我们必须添加一个指定路由处理器,或者,将请求交还给 HttpControllerDispatcher,如代码片段 3-22 所示。使用这个技术,只要在最后添加 HttpControllerDispatcher,在路由上可以有很多处理器,如果最后不添加 HttpControllerDispatcher 的话,就请求不到任何 Controller。
代码片段 3-22.使用指定路由处理器
这个可以给开发者提供很多灵活性的东西,尤其是,基于身份认证相关的场景,只要在需要身份认证的路由中增加安全相关的处理器。
代码演示
记录路由 /api/[sometink] 的日志,而不需要记录 /api/public/[something] 的。那么,我们需要消息处理器应用在指定的路由上,而不是在全局上处理所有的请求。
首先,我们做一个简单的 API 请求日志记录处理器,如代码片段 3-23 所示。
代码片段 3-23. 日志消息处理器,仅仅作用在指定的路由上。
在这里,我们没有必要深究 Request/Response 日志的实际实现方式。为了完成代码演示,我们只要将日志记录到内存中就可以。我们主要的关注点是在处理器作用在指定路由的机制。需要注意的是,要传 ASP.NET WEB API HttpConfiguration 对象给处理器。如代码片段 3-24 所示。
代码片段 3-24. 常规路由的注册与有处理器的注册
如果应用程序启动的话,效果应该如下
- 所有 /api/public/[something] 相关的请求不会被记录 Request/Response 的日志。
- 所有 /api/[something] 相关的请求会被记录 Request/Response 的日志,这主要是因为,上面的配置只是对这样的路由添加了处理器。