Search code examples
asp.net-mvcmultilingual

safe way to get the country from an IP Address in ASP.net MVC


I am working on multi language website , I can get Users IP Address, the problem is that I am looking for a very safe and trustworthy way to get IP and give me the country code , I want users confront their own language page while entering to my website, I have using once before, but it stops providing the service . Does any one have any idea how to do it? here is my code , and I really appreciate any help. I am looking for a real trustworthy one , google or some other API or even any code suggestion

    public async Task<ActionResult> Index()
    {


        try
        {
            string userIpAddress = this.Request.UserHostAddress;
            var client = new HttpClient
            {
                BaseAddress = new Uri("https:// `I need API HERE` ")
            };

            var response = await client.GetAsync(userIpAddress);

            var content = await response.Content.ReadAsStringAsync();

            var result = (Response)new XmlSerializer(typeof(Response)).Deserialize(new StringReader(content));
            var country_name = result.CountryName;
            var country_code = result.CountryCode;
            TempData["Country_code"] = country_code;
            TempData["Country_name"] = country_name;

            if (country_code == "FR")
            {
                return RedirectToAction("fr", "Home");
            }
            else if (country_code == "JP")
            {
                return RedirectToAction("jp", "Home");
            }
            else if (country_code == "DE")
            {
                return RedirectToAction("de", "Home");
            }

            else if (country_code == "NL")
            {
                return RedirectToAction("nl", "Home");
            }
            else if (country_code == "CN")
            {
                return RedirectToAction("cn", "Home");
            }
            else if (country_code == "DK")
            {
                return RedirectToAction("dk", "Home");
            }
            else if (country_code == "RU")
            {
                return RedirectToAction("ru", "Home");
            }
            else
            {
                return RedirectToAction("en", "Home");

            }


        }
        catch
        {
            return RedirectToAction("en", "Home");
        }


    }

Solution

  • Don't use IP addresses for this. It's not a good fit for the problem. For example, what if an English user takes their laptop on holiday with them, and uses your website from a different country? They would presumably still want to view the site in English, but you'll end up serving the content to them in a different language.

    Instead, use the Accept-Language request HTTP header:

    This header is a hint to be used when the server has no way of determining the language via another way, like a specific URL, that is controlled by an explicit user decision.

    An Example

    StringWithQualityHeaderValue preferredLanguage = null;
    if (Request.Headers.AllKeys.Contains("Accept-Language"))
    {
        preferredLanguage = Request.Headers["Accept-Language"]
            .Split(',')
            .Select(StringWithQualityHeaderValue.Parse)
            .OrderByDescending(s => s.Quality.GetValueOrDefault(1))
            .FirstOrDefault();
    }
    
    if (preferredLanguage?.Value == "fr")
    {
        return RedirectToAction("fr", "home");
    }
    // Check for other languages.    
    // ...
    // If no redirects match, default to English.
    return RedirectToAction("en", "home");