A C# library that provides geolocation information for IP addresses with MongoDB caching. Wraps third-party IP geolocation services (IpStack) to reduce API usage and costs through intelligent caching and session management.
$ dotnet add package GeoIpServicesGeoIpServices is an open-source C# library that provides geolocation information for IP addresses with intelligent MongoDB caching. It wraps third-party IP geolocation services (currently supporting IpStack) to significantly reduce API usage and costs through smart caching and session management.
Install the NuGet package using the .NET CLI:
dotnet add package GeoIpServices
Or via Package Manager Console:
Install-Package GeoIpServices
Add the following configuration to your appsettings.json:
{
"MongoDbSettings": {
"ConnectionString": "mongodb://localhost:27017",
"DatabaseName": "GeoIpDatabase"
},
"GeoIpSettings": {
"Controls": {
"SessionTimeoutInSeconds": 300,
"CacheDurationInHours": 24,
"MaxRoundRobinAttempts": 2,
"Priority": [ "IpStack" ]
},
"IpStack": {
"ApiPrefix": "https://api.ipstack.com/",
"ApiPostfix": "?access_key=YOUR_IPSTACK_API_KEY_HERE"
}
}
}
Configuration Options:
| Option | Default | Description |
|---|---|---|
SessionTimeoutInSeconds | 300 | How long lookup sessions remain active before expiring (MongoDB TTL) |
CacheDurationInHours | 24 | How long cached geolocation data is retained before expiring (MongoDB TTL) |
MaxRoundRobinAttempts | 1 | Number of retry cycles through all providers |
Priority | Required | Array of providers to use in order of preference (e.g., ["IpStack"]) |
ApiPostfix | Required | Your IpStack API key - Important: Keep this in user secrets or environment variables in production! |
Note: Both
SessionTimeoutInSecondsandCacheDurationInHoursuse MongoDB TTL indexes for automatic cleanup of expired documents.
Here's a complete example of a minimal API that returns geolocation information for the requesting IP:
using GeoIpServices;
using Microsoft.AspNetCore.Mvc;
using MongoDbService;
using System.Net;
using System.Net.Sockets;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Register MongoDB and GeoIp services
builder.Services.AddMongoDbServices();
builder.Services.AddGeoIpServices();
var app = builder.Build();
// Configure the HTTP request pipeline
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
// Endpoint to get geolocation info from visitor's IP
// You can inject either IGeoInfoService (interface) or GeoIpService (concrete class)
app.MapGet("/ipinfo", async ([FromServices] GeoIpService geoIpService, HttpRequest httpRequest) =>
{
var ipAddress = GetOriginIpV4(httpRequest);
if (ipAddress is null)
{
return Results.BadRequest("Unable to determine IP address");
}
var geoInfo = await geoIpService.GetGeoIpInfoFromIpv4(ipAddress);
if (geoInfo is null)
{
return Results.NotFound("Geolocation information not available");
}
return Results.Ok(geoInfo);
})
.WithName("GetGeoIpInfoFromIpv4")
.WithOpenApi();
// Helper method to extract client IP from request
IPAddress? GetOriginIpV4(HttpRequest httpRequest)
{
var xForwardedForHeader = httpRequest.Headers["X-Forwarded-For"];
var ipString = xForwardedForHeader.Select(s => s?.Trim()).FirstOrDefault();
if (string.IsNullOrWhiteSpace(ipString) || !IPAddress.TryParse(ipString, out IPAddress? clientIpAddress))
{
return null;
}
if (clientIpAddress.AddressFamily == AddressFamily.InterNetworkV6)
{
return clientIpAddress.MapToIPv4();
}
return clientIpAddress;
}
app.Run();
Issue: "Unable to fetch info for IP"
appsettings.jsonIssue: MongoDB connection errors
Issue: Always getting fresh data (cache not working)
CacheDurationInHours is set appropriatelyIssue: Configuration errors on startup
Priority, ApiPrefix, ApiPostfix)ApiPostfix starts with ?access_key=Priority contains at least one valid provider nameWe welcome contributions! If you find a bug or have an idea for improvement:
git checkout -b feature/amazing-feature)git commit -m 'Add some amazing feature')git push origin feature/amazing-feature)This project is licensed under the GNU General Public License v3.0. See the LICENSE file for details.
Happy coding! 🚀🌐📚