Querschnittsfunktionen, die für alle Services zur Ausführung gebracht werden sollen, können in Message Handler ausgelagert werden. Die nachfolgende Listing zeigt, wie man einen solchen Message-Handler durch Ableiten von DelegatingHandler implementieren kann.
public class LoggingHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
System.Threading.CancellationToken cancellationToken)
{
Debug.WriteLine("Begin Request: {0} {1}", request.Method, request.RequestUri);
return base.SendAsync(request, cancellationToken);
}
}
Damit ASP.NET Web API den Handler verwendet, ist er wie folgt - am besten in der Global.asax - zu registrieren.
GlobalConfiguration.Configuration.MessageHandlers.Add(new LoggingHandler());
Message-Handler können auch die abgefangene Nachricht auf der Ebene von HTTP bearbeiten. Ein gutes Beispiel dazu ist der aus der Dokumentation übernommene MethodOverrideHandler. Er löst das Problem, dass Firewalls mitunter DELETE- oder PUT-Anfragen blocken. Dazu setzt er auf die übliche Konvention, dass in diesen Fällen einfach POST zu verwenden ist. Das eigentliche Verb findet sich im HTTP-Header X-HTTP-Method-Override.
public class MethodOverrideHandler : DelegatingHandler
{
readonly string[] _methods = { "DELETE", "HEAD", "PUT" };
const string _header = "X-HTTP-Method-Override";
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken) {
// Check for HTTP POST with the X-HTTP-Method-Override header.
if (request.Method == HttpMethod.Post && request.Headers.Contains(_header)) {
// Check if the header value is in our methods list.
var method = request.Headers.GetValues(_header).FirstOrDefault();
if (_methods.Contains(method, StringComparer.InvariantCultureIgnoreCase))
{
// Change the request method.
request.Method = new HttpMethod(method);
}
}
return base.SendAsync(request, cancellationToken);
}
}