ASP.NET Web API and HttpRequestContext - StrathWeb

Strath

August 30th, 2013

ASP.NET Web API 2 and HttpRequestContext

Last week (23 August) ASP.NET Web API 2 RC (release candidate) was released on Nuget. One of the interesting changes in this version is the emergence of HttpRequestContext – which provides a shortcut, strongly typed access to the information which up to this point hidden inside of Request.Properties dictionary, as well as some additional useful bits and pieces.

Let’s explore what’s under the hood.

Getting Web API 2 RC

First of all, let’s install Web API 2 RC – and that you can do off nuget, simply using the -pre switch (this will grab the latest version, which no longer is Beta but RC).

This will install the latest assemblies which include the HttpRequestContext (part of System.Web.Http).

Exploring HttpRequestContext

The class deifnition is as follows:

The comments in the code pretty much explain the purpose of each property.

Most of these information (i.e. IncludeErrorDetail, isLocal etc) were already available inside of the HttpRequestMessage.Properties dictionary, although had to be extracted from there through the use of a predefined key and a cast, which was hardly convenient. In fact, even on this blog we previously resorted to this very technique.

The presence of UrlHelper here is a welcome addition, as it gives us access to link generetion outside of the controller context (i.e. in the formatter or message handler), which is definitely going to be useful. IPrincipal, on the other hand, will be helpful in testing.

HttpRequestContext can be obtained from any HttpRequestMessage (you have access to the current request pretty much anywhere in the Web API pipeline) through an extension method that is part of the latest RC package too:

This also reveals to us, that internally the context itself is simply stored in the same HttpRequestMessage.Properties dictionary as all the other request-specific information.

On a side note, the Web API team also included a couple of other extension methods, that provide direct access to specific value stored inside that dictionary, i.e.:

  • public static X509Certificate2 GetClientCertificate(this HttpRequestMessage request)
  • public static IHttpRouteData GetRouteData(this HttpRequestMessage request)
  • public static bool IsLocal(this HttpRequestMessage request)
  • public static bool ShouldIncludeErrorDetail(this HttpRequestMessage request)
  • public static bool IsBatchRequest(this HttpRequestMessage request)

Internally they all go through RequestContext anyway, so they are merely convenience additions.

Redundancy of information

While the addition of the context is generally a good idea, it does contribute to cluttering the overall framework API a little bit.

For example: since HttpRequestContext gives you access to the current HttpConfiguration, when you are working with a controller, you now have at least 7 different ways of getting hold the configuration (there is probably more :-)

  • Configuration property on ApiController base class
  • Configuration property on the Request property on the ApiController base class
  • Configuration property on the RequestContext property on the ApiController base class
  • Configuration property on the RequestContext property obtained by calling GetRequestContext() method on the Request object on the ApiController base class
  • Configuration property on the RequestContext property on the ControllerContext on the ApiController base class
  • Configuration property on the ControllerDescriptor property on the ControllerContext on the ApiController base class
  • – in Web host you can also access the static GlobalConfiguration.Configuration

while this is not necessarily bad, there is some amount of noise here, isn’t there?

IMHO, the RequestContext on the ApiController or ControllerContext are unnecessary. It would make more to keep the consistency and promote obtaining of the HttpRequestContext always through the GetRequestContext() method on the HttpRequestMessage, as that’s what you have to do in the handlers, filters, formatters anyway.

In fact, it is especially confusing to have Request and RequestContext properties side by side (again, see ApiController!

I would also like to see the RequestContext surface the IP of the caller – instead of us having to resort to homebrewed extensions.

Summary

Regardless of some redundancy in the API design, there is definitely some good value with the HttpRequestContext – and I’m sure it will become a good “friend” of yours in the future Web API development.

Be Sociable, Share!