HttpErrorHandler & HttpRequestMessage context

Topics: Web Api
Jan 11, 2012 at 1:44 PM

Hi there.

I am using an HttpErrorHandler for my error handling for my WebApi pipeline.  One problem I am currently having is gaining access to the current HttpRequestMessage from within the OnTryProvideResponse method.  I grabbed this example off of http://wcf.codeplex.com/discussions/276044 which I am going to use as an example here.

public class AlwaysOkErrorHandler : HttpErrorHandler
    {
        protected override bool OnTryProvideResponse(Exception exception, ref HttpResponseMessage message)
        {
          //logic goes here.. such as this always returns 200 in this case
            message = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StringContent(exception.Message)
            };
            return true;
        }
    }

Provided that the exception that is being thrown does NOT inherit from Microsoft.ApplicationServer.Http.Dispatcher.HttpResponseException, I have found it very difficult to grab the request information that was submitted in which this error is associated. This information could be very valuable for logging purposes (as well as other things I am sure).

My question is:  If a normal exception (ie. not one that inherits Microsoft.ApplicationServer.Http.Dispatcher.HttpResponseException) is thrown and caught in the error handler, how can you gain context to the HttpRequestMessage?  Currently I am pulling request information from the HttpContext.Current.Request which feels extremely dirty...

Thanks for any help in advance!

Jan 11, 2012 at 3:18 PM
DotNetRockStar wrote:

Hi there.

I am using an HttpErrorHandler for my error handling for my WebApi pipeline.  One problem I am currently having is gaining access to the current HttpRequestMessage from within the OnTryProvideResponse method.  I grabbed this example off of http://wcf.codeplex.com/discussions/276044 which I am going to use as an example here.

public class AlwaysOkErrorHandler : HttpErrorHandler
    {
        protected override bool OnTryProvideResponse(Exception exception, ref HttpResponseMessage message)
        {
          //logic goes here.. such as this always returns 200 in this case
            message = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StringContent(exception.Message)
            };
            return true;
        }
    }

Provided that the exception that is being thrown does NOT inherit from Microsoft.ApplicationServer.Http.Dispatcher.HttpResponseException, I have found it very difficult to grab the request information that was submitted in which this error is associated. This information could be very valuable for logging purposes (as well as other things I am sure).

My question is:  If a normal exception (ie. not one that inherits Microsoft.ApplicationServer.Http.Dispatcher.HttpResponseException) is thrown and caught in the error handler, how can you gain context to the HttpRequestMessage?  Currently I am pulling request information from the HttpContext.Current.Request which feels extremely dirty...

Thanks for any help in advance!


Closing this thread as it appears as if there is another thread concerning this matter.  http://wcf.codeplex.com/discussions/281421

Feb 10, 2012 at 3:38 PM
Edited Feb 10, 2012 at 3:42 PM

Sorry, probably bad form replying to a closed thread but this solution didn't seem to fit with the problem faced in the other thread. Here's how I solved this:

public class HttpOkMessageHandler : DelegatingHandler

   {

       protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)

       {

           return base.SendAsync(request, cancellationToken).ContinueWith(

               task =>

                   {

                       HttpResponseMessage response = task.Result;

                       if (response.StatusCode != HttpStatusCode.OK && request.Headers.Contains("X-HTTP-Status-Unsupported"))

                       {

                           response.Content = new ObjectContent(typeof(ErrorResource), new ErrorResource(response.StatusCode));

                           response.StatusCode = HttpStatusCode.OK;                          

                       }

 

                       return response;

                    });

       }

   }

 

Feb 11, 2012 at 9:04 AM

Out of interest here is how I've accessed the request from an error handler (by looking at the WCF web api source code). This enables me to get hold of stuff like the URL and headers to include in error logs:

        internal static HttpRequestMessage GetRequestMessage()
        {
            var context = OperationContext.Current;
            if (context != null)
            {
                RequestContext requestContext = context.RequestContext;
                if (requestContext != null)
                {
                    Message message = requestContext.RequestMessage;
                    if (message != null)
                    {
                        return message.ToHttpRequestMessage();
                    }
                }
            }

            return null;
        }