Retrieving the client's IP address in ASP.NET Web API

Strath

May 23rd, 2013

Retrieving the client’s IP address in ASP.NET Web API

One of the common tasks, for logging or authorization purposes, is to obtain the IP address of the client accessing your Web API.

There are different ways to achieve this depending on whether you are web hosting (through HttpContext) or whether you are self hosting (through WCF’s RemoteEndpointMessageProperty).

To avoid the redundant code, we can unify those approaches under a single extension method, which you can use across all your projects.

Obtaining the client IP in ASP.NET Web API web host

To get the IP from the incoming request in the web host scenarios, we have to get hold of HttpContext. This is done very easily, through the Ms_HttpContext request property key.

Of course this requires that you reference System.Web as that’s where HttpContextWrapper resides.

Obtaining the client IP in ASP.NET Web API self host

In self host scenarios, you can access client information through RemoteEndpointMessageProperty, which, similarly to web host, is stored in the properties of the incoming HttpRequestMessage. The property is added to each incoming message to a WCF service through both the HTTP and TCP transports. Since Web API self host uses WCF core, it’s there for our API host too.

In this case, we look for the property key “RemoteEndpointMessageProperty.Name” which simply is the fully qualified name – “System.ServceModel.Channels.RemoteEndpointMessageProperty”.

Since we cast to RemoteEndpointMessageProperty we need to reference System.ServiceModel.dll, as that’s where this class is declared. You can read up more on MSDN.

Unifying the two approaches

Of course it’s not very convenient to have two separate bits of code that you have to drag along to each type of project (self vs web host). We can easily wrap both approaches in a single extension method, and hang it off HttpRequestMethod.

Since we don’t want self host to reference System.Web, and we don’t want web host to unnecessarily reference System.ServiceModel, we could use dynamic to avoid strong typing and defer the type evaluation until runtime (by-pass compile time type check). Since we deal with, effectively, an if-else scenario here, only one code path will ever be used in each type of hosting anyway.

Here’s the complete solution:

You can now safely use this extension in each type of Web API project, and not worry about having to reference unnecessary DLLs just to make the code compile (as we would have to, if we wouldn’t use dynamic).

It’s important to mention that you have to reference System.ServiceModel in self hosted projects, as it’s not included by default (contrary to System.Web always being there for web host).

You can now use this anywhere, where you have access to the current HttpRequestMessage. For example:

If you use WebApiContrib (and you should!), I have added this extension method there too.

Be Sociable, Share!