BoxesNLines.Geolocation
1.0.1
dotnet add package BoxesNLines.Geolocation --version 1.0.1
NuGet\Install-Package BoxesNLines.Geolocation -Version 1.0.1
<PackageReference Include="BoxesNLines.Geolocation" Version="1.0.1" />
<PackageVersion Include="BoxesNLines.Geolocation" Version="1.0.1" />
<PackageReference Include="BoxesNLines.Geolocation" />
paket add BoxesNLines.Geolocation --version 1.0.1
#r "nuget: BoxesNLines.Geolocation, 1.0.1"
#:package BoxesNLines.Geolocation@1.0.1
#addin nuget:?package=BoxesNLines.Geolocation&version=1.0.1
#tool nuget:?package=BoxesNLines.Geolocation&version=1.0.1
BoxesNLines.Geolocation - .NET SDK
Official .NET SDK for the BoxesNLines Geolocation API. Provides GeolocationClient for geographic lookups using API key authentication.
Requirements
- .NET 8.0, 9.0, or 10.0
Architecture
graph LR
App["Your Application"] --> Client["GeolocationClient"]
Client --> Cache{"LRU Cache\nenabled?"}
Cache -->|hit| App
Cache -->|miss| HTTP["ApiHttpClient"]
HTTP -->|"X-API-Key"| Gateway["api.boxesnlines.com\n/geo/*"]
HTTP -->|429| Retry["RateLimitHandler\nRetry-After"]
HTTP -->|5xx| Backoff["RetryHandler\nExponential Backoff"]
Retry --> HTTP
Backoff --> HTTP
Gateway --> HTTP
HTTP --> Cache
Installation
dotnet add package BoxesNLines.Geolocation
Quick Start
using BoxesNLines.Geolocation;
using var client = new GeolocationClient(new GeolocationClientOptions
{
ApiKey = "bnl_your_api_key"
});
// Get country from GPS coordinates (returns ISO 3166-1 alpha-3 code)
var country = await client.GetCountryFromGpsAsync(40.7128, -74.0060);
Console.WriteLine(country.Data); // "USA"
// Get subdivision (returns ISO 3166-2 code)
var subdivision = await client.GetSubdivisionFromGpsAsync(40.7128, -74.0060);
Console.WriteLine(subdivision.Data); // "US-NY"
// Check if coordinates are within a country
var inUs = await client.IsInCountryAsync("USA", 40.7128, -74.0060);
Console.WriteLine(inUs.Data); // true
// Check if coordinates are within a subdivision
var inNy = await client.IsInSubdivisionAsync("US-NY", 40.7128, -74.0060);
Console.WriteLine(inNy.Data); // true
GeolocationClient implements IDisposable. Use using when constructing it directly, or let the DI container manage its lifetime.
Dependency Injection
Register the client with the .NET DI container using the provided extension method:
using BoxesNLines.Geolocation.DependencyInjection;
builder.Services.AddBoxesNLinesGeolocation(opt =>
{
opt.ApiKey = builder.Configuration["BoxesNLines:ApiKey"]!;
});
Then inject IGeolocationClient into your services:
public class MyService(IGeolocationClient geo)
{
public async Task<string> GetCountry(double lat, double lon)
{
var result = await geo.GetCountryFromGpsAsync(lat, lon);
return result.Data;
}
}
Configuration
GeolocationClientOptions
| Property | Type | Default | Description |
|---|---|---|---|
ApiKey |
string |
(required) | Your BoxesNLines API key |
BaseUrl |
string |
https://api.boxesnlines.com |
API base URL |
TimeoutSeconds |
int |
30 |
HTTP request timeout |
MaxRetries |
int |
3 |
Max retries on rate-limit (429) and server errors (5xx) |
Cache.Enabled |
bool |
true |
Enable built-in LRU response cache |
Cache.DefaultTtl |
TimeSpan |
5 minutes |
Cache entry lifetime |
Cache.MaxEntries |
int |
1000 |
Max cached entries |
CustomCache |
IGeolocationCache? |
null |
Pluggable cache implementation (see below) |
NoCacheWarningInterval |
int |
100 |
Emit a diagnostic trace warning every N requests when caching is disabled. Set to 0 to suppress. |
Error Handling
All API errors throw typed exceptions derived from ApiException:
using BoxesNLines.Geolocation.Errors;
try
{
await client.GetCountryFromGpsAsync(lat, lon);
}
catch (RateLimitException ex)
{
Console.WriteLine($"Rate limited. Retry after {ex.RetryAfterSeconds}s");
}
catch (AuthException)
{
Console.WriteLine("Invalid or expired API key");
}
catch (NotFoundException)
{
Console.WriteLine("No country found for these coordinates");
}
catch (ConflictException)
{
Console.WriteLine("Request conflict (HTTP 409)");
}
catch (ValidationException ex)
{
foreach (var (field, errors) in ex.FieldErrors)
Console.WriteLine($"{field}: {string.Join(", ", errors)}");
}
catch (ApiException ex)
{
Console.WriteLine($"API error {ex.StatusCode}: {ex.Message}");
}
The SDK automatically retries 429 responses using the Retry-After header value, and retries 5xx responses with exponential backoff. Retries are bounded by MaxRetries.
Rate Limit Information
Every successful response includes rate limit information from the response headers:
var response = await client.GetCountryFromGpsAsync(lat, lon);
Console.WriteLine($"Burst: {response.RateLimitInfo.BurstRemaining}/{response.RateLimitInfo.BurstLimit}");
Console.WriteLine($"Quota: {response.RateLimitInfo.QuotaRemaining}/{response.RateLimitInfo.QuotaLimit}");
Caching
The SDK ships with a thread-safe in-memory LRU cache enabled by default. Cache keys are derived from the request path (e.g. GET:/geo/country/fromGps/40.712800,-74.006000).
To clear the cache:
await client.ClearCacheAsync();
To disable the built-in cache:
var client = new GeolocationClient(new GeolocationClientOptions
{
ApiKey = "bnl_your_api_key",
Cache = new CacheOptions { Enabled = false }
});
Custom Cache
Provide any distributed or custom cache by implementing IGeolocationCache and setting CustomCache. When CustomCache is set, the built-in LRU cache is bypassed entirely.
public sealed class MyRedisCache : IGeolocationCache
{
private readonly IConnectionMultiplexer _multiplexer;
private readonly IDatabase _db;
public MyRedisCache(IConnectionMultiplexer redis)
{
_multiplexer = redis;
_db = redis.GetDatabase();
}
public async Task<T?> GetAsync<T>(string key, CancellationToken ct = default)
{
var value = await _db.StringGetAsync(key);
return value.HasValue ? JsonSerializer.Deserialize<T>(value!) : default;
}
public async Task SetAsync<T>(string key, T value, TimeSpan? ttl = null, CancellationToken ct = default)
{
var json = JsonSerializer.Serialize(value);
await _db.StringSetAsync(key, json, ttl);
}
public async Task RemoveAsync(string key, CancellationToken ct = default) =>
await _db.KeyDeleteAsync(key);
public async Task ClearAsync(CancellationToken ct = default)
{
var endpoints = _multiplexer.GetEndPoints();
foreach (var endpoint in endpoints)
{
var server = _multiplexer.GetServer(endpoint);
var keys = server.Keys(pattern: "GET:*");
foreach (var key in keys)
await _db.KeyDeleteAsync(key).ConfigureAwait(false);
}
}
}
var client = new GeolocationClient(new GeolocationClientOptions
{
ApiKey = "bnl_your_api_key",
CustomCache = new MyRedisCache(connectionMultiplexer)
});
The ClearAsync implementation uses server.Keys(pattern: "GET:*") to delete only SDK-owned keys, avoiding collateral damage on a shared Redis instance.
A complete Redis adapter example is available in samples/redis-cache/.
Samples
| Sample | Description |
|---|---|
samples/quickstart/ |
Minimal usage : reverse geocode three cities, print alpha-3 codes |
samples/redis-cache/ |
Custom Redis-backed IGeolocationCache adapter using GET:* key scoping |
samples/gdpr-compliance/ |
ASP.NET Core Web API enforcing GDPR policy based on visitor country |
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Http (>= 8.0.1)
- Microsoft.Extensions.Options (>= 8.0.2)
-
net8.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Http (>= 8.0.1)
- Microsoft.Extensions.Options (>= 8.0.2)
-
net9.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Http (>= 8.0.1)
- Microsoft.Extensions.Options (>= 8.0.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.