GeoIP .NET API

repository·main·Indexed 18 days ago

https://github.com/maxmind/geoip2-dotnet

A client library for accessing MaxMind's GeoIP and GeoLite web services and local .mmdb databases to perform IP geolocation lookups. It provides the WebServiceClient for web-based queries and the DatabaseReader for local database lookups, including support for City, Country, ASN, ISP, Domain, Connection-Type, and Anonymous IP data. The library is thread-safe and compatible with ASP.NET Core dependency injection.

Tokens
6.6K
Snippets
16
Records
33
Agent score
14%

What's inside maxmind-geoip2-dotnet

  1. Multi-threaded usage with DatabaseReader

    main
    The GeoIP .NET API is fully thread-safe. For multi-threaded applications, it is recommended to create a single DatabaseReader object and share it across all threads to optimize performance and resource usage.
  2. Use the Anonymizer object for Risk and VPN data

    main

    Starting in v5.4.0, MaxMind introduced the Anonymizer object to provide detailed insights into network anonymity.

    Important Migration: The following properties on MaxMind.GeoIP2.Model.Traits are marked Obsolete and should be replaced by the Anonymizer object:

    • IsAnonymous
    • IsAnonymousVpn
    • IsHostingProvider
    • IsPublicProxy
    • IsResidentialProxy
    • IsTorExitNode

    New Anonymizer Properties:

    • Confidence: Score (1-99) representing percent confidence the network is an active VPN.
    • IsAnonymous: Indicates if the IP belongs to an anonymous network.
    • IsAnonymousVpn: True if registered to an anonymous VPN provider.
    • IsHostingProvider: True if the IP belongs to a hosting or VPN provider.
    • IsPublicProxy: True if the IP is a public proxy.
    • IsResidentialProxy: True if the IP is on a suspected anonymizing network belonging to a residential ISP.
    • IsTorExitNode: True if the IP is a Tor exit node.
    • NetworkLastSeen: Last day the network was sighted (available on .NET 6.0+ as DateOnly).
    • ProviderName: The name of the associated VPN provider.
  3. Understanding returned data and completeness

    main

    Attributes in returned records may be unpopulated depending on the specific endpoint used and the availability of data for a given IP address.

    Note: The only piece of data guaranteed to be returned is the ipAddress attribute found in the MaxMind.GeoIP2.Traits record.

  4. How to use the WebServiceClient

    main

    The WebServiceClient is used to access MaxMind's web services.

    Key usage patterns:

    • Thread Safety: The object is safe to share across threads.
    • Connection Reuse: You should reuse a single WebServiceClient instance for multiple requests to avoid creating new connections for every request.
    • Lifecycle: You must dispose of the object when finished to ensure connections are closed and resources are returned to the system.
    • Initialization: Create it with your Account ID and License Key. You can optionally specify a host, fall-back locales, or timeout.

    Host Options:

    • Default: Production GeoIP web service.
    • geolite.info: Queries the GeoLite web service.
    • sandbox.maxmind.com: Queries the Sandbox GeoIP web service.
    // Standard usage
    var client = new WebServiceClient(42, "license_key1");
    
    // GeoLite usage
    var client = new WebServiceClient(42, "license_key1", host: "geolite.info");
    
    // Sandbox usage
    var client = new WebServiceClient(42, "license_key1", host: "sandbox.maxmind.com");
  5. Recommended keys for database or dictionary lookups

    main

    Do not use values from Names properties as keys in databases or dictionaries, as they may change between releases. Instead, use the following stable identifiers:

    • City: City.GeoNameId
    • Continent: Continent.Code or Continent.GeoNameId
    • Country / RepresentedCountry: Country.IsoCode or Country.GeoNameId
    • Subdivision: Subdivision.IsoCode or Subdivision.GeoNameId
  6. Configure WebServiceClient in ASP.NET Core

    main

    To use the WebServiceClient with the HttpClient factory pattern as a Typed client in ASP.NET Core, follow these steps:

    1. Update Program.cs to configure options from your configuration section and register the client for dependency injection:
    builder.Services.Configure<WebServiceClientOptions>(builder.Configuration.GetSection("MaxMind"));
    builder.Services.AddHttpClient<WebServiceClient>();
    1. Update appsettings.json with your credentials and optional settings:
    "MaxMind": {
      "AccountId": 123456,
      "LicenseKey": "1234567890",
      // "Timeout": 3000,
      // "Host": "geolite.info"
    }
    1. Inject and use the WebServiceClient in your controllers or services.
    [ApiController]
    [Route("[controller]")]
    public class MaxMindController : ControllerBase
    {
        private readonly WebServiceClient _maxMindClient;
    
        public MaxMindController(WebServiceClient maxMindClient)
        {
            _maxMindClient = maxMindClient;
        }
    
        [HttpGet]
        public async Task<string> Get()
        {
            var location = await _maxMindClient.CountryAsync();
            return location.Country.Name;
        }
    }
  7. Migrate to GeoIP2 .NET v6.0+ (Breaking Changes)

    main

    Version 6.0 introduced significant breaking changes due to a shift in the underlying data model and deserialization logic. If you are upgrading from v5.x or earlier, you must address the following:

    • Model Types: All model and response classes are now C# records instead of classes.
    • Initialization: Constructor-based initialization is no longer supported. You must use object initializer syntax.
      • Old: new Traits(domain: "example.com")
      • New: new Traits { Domain = "example.com" }
    • Immutability: Properties now use init setters. To modify a model, use the with expression pattern via the WithLocales() method instead of in-place mutation.
    • ToString Behavior: The custom ToString() on NamedEntity subclasses (City, Country, etc.) has been removed. Use the .Name property directly to get the entity name.
    • Memory Mapping: FileAccessMode.Memory and the DatabaseReader(Stream) constructor now use anonymous memory-mapped files. This removes the ~2.1 GiB size limit but may not work in environments like WASM, mobile/sandboxed runtimes, or hardened containers with restricted shared-memory syscalls.
    • Nullability: TryXxx methods now use the [MaybeNullWhen(false)] attribute, allowing the compiler to understand that out parameters are non-null when the method returns true.
    // Old syntax (v5.x and below)
    var traits = new Traits("example.com");
    
    // New syntax (v6.0+)
    var traits = new Traits { Domain = "example.com" };
  8. Use the Database API with DatabaseReader

    main

    To use local GeoIP databases instead of web services, use the DatabaseReader class.

    Usage Steps:

    1. Create a new DatabaseReader instance by providing the file path to your GeoIP database.
    2. You may optionally specify the file access mode.
    3. Call the appropriate method (e.g., City()) with the IP address you want to look up.

    Best Practice: Reusing the DatabaseReader object is highly recommended. Creating a new instance is relatively expensive because it must read the file's metadata into memory.

  9. Handle Database and Web Service exceptions

    main

    The library uses a hierarchy of exceptions for error handling:

    Database Errors

    • MaxMind.Db.InvalidDatabaseException: Thrown if the database file is corrupt or invalid.
    • AddressNotFoundException: Thrown if the requested IP address is not in the database.

    Web Service Errors

    All web service exceptions inherit from GeoIP2Exception.

    • AddressNotFoundException: Thrown when the web service returns an explicit error document indicating the address was not found.
    • AuthenticationException: Thrown for authentication errors.
    • InvalidRequestException: Thrown for invalid requests.
    • OutOfQueriesException: Thrown when query limits are exceeded.
    • HttpException: Thrown for transport errors (e.g., 500 errors) or unexpected status codes.
    • GeoIP2Exception: Thrown if the web service returns a 200 OK but the response body is invalid.
  10. Perform lookups using the ASN Database

    main

    Use the Asn method on a DatabaseReader instance initialized with an ASN .mmdb file to retrieve Autonomous System Number and Organization information.

    using (var reader = new DatabaseReader("GeoLite2-ASN.mmdb"))
    {
        var response = reader.Asn("85.25.43.84");
        Console.WriteLine(response.AutonomousSystemNumber); // 217
        Console.WriteLine(response.AutonomousSystemOrganization); // 'University of Minnesota'
        Console.WriteLine(response.IPAddress); // '128.101.101.101'
    }