One way to achieve this is to write a DelegatingHandler to intercept the response before it is sent back to the client, and then register information about those requests that return errors.
public class RepsonseInterceptor : DelegatingHandler { protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { var response = await base.SendAsync(request, cancellationToken); LogResponse(request, response); return response; } public void LogResponse(HttpRequestMessage request, HttpResponseMessage response) { HttpStatusCode status = response.StatusCode;
Then add this to Application_Start in the Global.asax.cs file:
GlobalConfiguration.Configuration.MessageHandlers.Add(new ResponseInterceptor());
EDIT:
If you do not want to execute a handler for all routes, you can add it as a message handler on the path to the routes that you want, and not globally:
config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional }, constraints: null, handler: new ResponseInterceptor() );
If you are using the .NET Framework 4.0, you need to change the SendAsync method for the handler as follows:
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { return base.SendAsync(request, cancellationToken) .ContinueWith(task => { var response = task.Result; LogResponse(request, response); return response; }); }
I think it would be wise to just use this MessageHandler if you can get all the information you need to enter from the Request and Response objects, although I have not fully tested it.