, , Codeplex ASP.NET Web Stack repo.
, . :
, : MyMessageHandler MyMessageHandler2. , , :
protected void Application_Start(object sender, EventArgs e) {
RouteConfig.RegisterRoutes(GlobalConfiguration.Configuration.Routes);
GlobalConfiguration.Configuration.MessageHandlers.Add(new MyMessageHandler());
GlobalConfiguration.Configuration.MessageHandlers.Add(new MyMessageHandler2());
}
, MyMessageHandler , MyMessageHandler2 - , FIFO.
, , Initialize HttpServer CreatePipeline System.Net.Http.HttpClientFactory ( HttpPipelineFactory.Create , .) CreatePipeline : HttpMessageHandler IEnumerable<DelegatingHandler>. HttpServer.Initialize System.Web.Http.Dispatcher.HttpControllerDispatcher HttpMessageHandler HttpMessageHandler HttpConfiguration.MessageHandlers IEnumerable<DelegatingHandler>.
CreatePipeline, IMO:
public static HttpMessageHandler CreatePipeline(HttpMessageHandler innerHandler, IEnumerable<DelegatingHandler> handlers)
{
if (innerHandler == null)
{
throw Error.ArgumentNull("innerHandler");
}
if (handlers == null)
{
return innerHandler;
}
HttpMessageHandler pipeline = innerHandler;
IEnumerable<DelegatingHandler> reversedHandlers = handlers.Reverse();
foreach (DelegatingHandler handler in reversedHandlers)
{
if (handler == null)
{
throw Error.Argument("handlers", Properties.Resources.DelegatingHandlerArrayContainsNullItem, typeof(DelegatingHandler).Name);
}
if (handler.InnerHandler != null)
{
throw Error.Argument("handlers", Properties.Resources.DelegatingHandlerArrayHasNonNullInnerHandler, typeof(DelegatingHandler).Name, "InnerHandler", handler.GetType().Name);
}
handler.InnerHandler = pipeline;
pipeline = handler;
}
return pipeline;
}
, , : HttpControllerDispatcher - , .
, . , , , , , . , . ( , ), , .
, , , :
public class MyMessageHandler : DelegatingHandler {
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) {
return base.SendAsync(request, cancellationToken).ContinueWith(task => {
var response = task.Result;
return response;
});
}
}
:
public class MyMessageHandler2 : DelegatingHandler {
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) {
return base.SendAsync(request, cancellationToken).ContinueWith(task => {
var response = task.Result;
return response;
});
}
}
As we continued, our message handlers will be returned on the way back to the client in FILO order. Thus, the continuation method inside MyMessageHandler2will be the first to be called on the return trip, and the second inside MyMessageHandlerwill be the second.