Adding Request.IsLocal to ASP.NET Web API

· 374 words · 2 minutes to read

I was recently asked how to filter out local requests in Web API. Indeed, one of the more useful things that developers got used to work with in traditional ASP.NET (and the System.Web.dll) was the ability to quickly check if a given request is a local one or not - by simply calling the IsLocal boolean property on HttpRequest.

This has been omitted from HttpRequestMessage in the new HTTP object model, around which Web API is built, but Web API still keeps track of that information under the hood, so you can easily write a simple extension method to bring back the old familiar syntax.

More after the jump.

Request.isLocal in Web API 🔗

In the old HTTP model (System.Web.dll), Request.IsLocal returned true if the IP address of the request originator was localhost (or 127.0.0.1) or if the IP address of the request is the same as the server’s IP address.

While HttpRequestMessage indeed does not have IsLocal anymore, Web API will track this information in a Lazy inside the Request.Properties dictionary, under a rather vague MS_IsLocal key.

With this information, we can now write a very simple extension method:

public static class HttpRequestMessageExtensions  
{  
public static bool IsLocal(this HttpRequestMessage request)  
{  
var localFlag = request.Properties["MS_IsLocal"] as Lazy<bool>;  
return localFlag != null && localFlag.Value;  
}  
}  

This now allows you to simply call isLocal() anywhere in the Web API pipeline where the framework gives you access to the incoming request.

In an ApiController:

public HttpResponseMessage Get()  
{  
if (Request.IsLocal()) {  
//do stuff  
}  
}  

In a handler:

public class MyHandler : DelegatingHandler  
{  
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)  
{  
if (request.IsLocal())  
{  
//do stuff  
}  
return base.SendAsync(request, cancellationToken);  
}  
}  

In a filter:

public class MyFilter : ActionFilterAttribute  
{  
public override void OnActionExecuting(HttpActionContext actionContext)  
{  
if (actionContext.Request.IsLocal())  
{  
//do stuff  
}  
base.OnActionExecuting(actionContext);  
}  
}  

Or even in a formatter:

public class MyFormatter : JsonMediaTypeFormatter  
{  
public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, MediaTypeHeaderValue mediaType)  
{  
if (request.IsLocal())  
{  
//do stuff  
}  
return base.GetPerRequestFormatterInstance(type, request, mediaType);  
}  
}  

By the way - contrary to pulling this information out of HttpContext, this approach works for both web-host and self-host.

All in all - a very simple 2-line extension method, but quite useful for development purposes.

About


Hi! I'm Filip W., a cloud architect from Zürich 🇨🇭. I like Toronto Maple Leafs 🇨🇦, Rancid and quantum computing. Oh, and I love the Lowlands 🏴󠁧󠁢󠁳󠁣󠁴󠁿.

You can find me on Github and on Mastodon.

My Introduction to Quantum Computing with Q# and QDK book
Microsoft MVP