How do I correct the error Invalid JSON primitive while trying to find a user's geographic location using IP address?

Donald Symmons 3,066 Reputation points
2023-06-13T05:46:21.7333333+00:00

In trying to find a visitor's geographic location (GeoLocation) using IP Address, I got this error. May I please know what this means and how do I correct and make it work without error?

JSON

Visitor’s geographic location (Geolocation) was to be determined with the help of FreeGeoIP API which is IP to Location API and returns the visitor’s geographic location (Geolocation) details like Country, City, Region, Zip Code, Latitude, Longitude and Time zone using the Client IP Address of his machine.

I Installed the TimeZoneConverter package from Nuget for this.

Here is my code:

Namspaces

using System.Net;
using System.Web.Script.Serialization;
using System.Data.SqlClient;
using System.Configuration;
using TimeZoneConverter;

public class LocationModel
        {
            public string IP { get; set; }
            public string Country_Code { get; set; }
            public string Country_Name { get; set; }
            public string Region_Code { get; set; }
            public string Region_Name { get; set; }
            public string City { get; set; }
            public string Zip_Code { get; set; }
            public string Time_Zone { get; set; }
            public string Latitude { get; set; }
            public string Longitude { get; set; }
            public string Metro_Code { get; set; }
        }

private LocationModel GetLocation()
        {
           try
            {
                string ipAddress = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                if (string.IsNullOrEmpty(ipAddress))
                {
                    ipAddress = Request.ServerVariables["REMOTE_ADDR"];
                }
                LocationModel location = new LocationModel();
                string url = string.Format("http://freegeoip.net/json/{0}", ipAddress);
                using (WebClient client = new WebClient())
                {
                    string json = client.DownloadString(url);
                    return new JavaScriptSerializer().Deserialize<LocationModel>(json);
                }
           }
            catch (SqlException ex)
            {
                string msg = "Error:";
                msg += ex.Message;
                throw new Exception(msg);
            }
        }

I need help to correct this error. Thnak you.

Developer technologies .NET Other
Developer technologies ASP.NET Other
Developer technologies C#
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. Lan Huang-MSFT 30,186 Reputation points Microsoft External Staff
    2023-06-13T07:37:22.83+00:00

    Hi @Donald Symmons,

    According to the documentation, the old freegeoip API has been deprecated since March 31, 2018.

    https://github.com/apilayer/freegeoip/#freegeoip---important-announcement

    As of March 31 2018 the old freegeoip API is deprecated and a completely re-designed API is now accessible at [http://api.ipstack.com]. While the new API offers the same capabilities as the old one and also has the option of returning data in the legacy format, the API URL has now changed and all users are required to sign up for a free API Access Key to use the service.

    1.Get a free ipstack Account and Access Key

    2.Integrate the new API URL

    JSON Example: http://api.ipstack.com/186.116.207.169?access_key =YOUR_ACCESS_KEY&output=json&legacy=1

    Here's the code for reference:

                string ipAddress = "167.220.255.118";
                string url = string.Format("http://api.ipstack.com/{0}?access_key=your API Access Key", ipAddress);
    
                using (WebClient client = new WebClient())
                {
                    string json = client.DownloadString(url);
                    Location location = new Location();
                    location = new JavaScriptSerializer().Deserialize<Location>(json);
                    lblPostalCode.Text = location.Country_Name;
                }
    

    Best regards,
    Lan Huang


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  2. Bruce (SqlWork.com) 77,686 Reputation points Volunteer Moderator
    2023-06-13T16:00:13.3333333+00:00

    the error means the json string is not valid. display the actual json string for more help.

    0 comments No comments

  3. Donald Symmons 3,066 Reputation points
    2023-06-23T00:35:09.4+00:00

    Here it is. This gives me the right user local date and time

    private Location GetLocation()
            {
                string ipAddress;
                ipAddress = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                if (ipAddress == "" || ipAddress == null)
                    ipAddress = Request.ServerVariables["REMOTE_ADDR"];
                string APIKey = "MY_ACCESS_KEY";
                string url = string.Format("https://api.ip2location.io/?key={0}&ip={1}&format=json", APIKey, ipAddress);
                ServicePointManager.Expect100Continue = true;
                ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
                using (WebClient client = new WebClient())
                {
                    string json = client.DownloadString(url);
                    Location location = new JavaScriptSerializer().Deserialize<Location>(json);
                    return location;
                }
            }
    
    public string GetTimeZoneNameByOffsetTime(string offset)
            {
                return TimeZoneInfo.GetSystemTimeZones().FirstOrDefault(x => x.BaseUtcOffset == TimeSpan.Parse(offset)).StandardName;
            }
    
            public class Location
            {
                public string ip { get; set; }
                public string country_code { get; set; }
                public string country_name { get; set; }
                public string region_name { get; set; }
                public string city_name { get; set; }
                public double latitude { get; set; }
                public double longitude { get; set; }
                public string zip_code { get; set; }
                public string time_zone { get; set; }
                public string asn { get; set; }
                public string @as { get; set; }
                public bool is_proxy { get; set; }
            }
    
    private void LastLogin()
            {
                string connectionString = ConfigurationManager.ConnectionStrings["ConString"].ConnectionString;
                using (SqlConnection con = new SqlConnection(connectionString))
                {
                    using (SqlCommand cmd = new SqlCommand("SELECT LastLogin FROM Users WHERE Id = @Id", con))
                    {
                        cmd.Parameters.AddWithValue("@Id", Session["user"]);
                        con.Open();
                        DateTime time1 = Convert.ToDateTime(Session["LastLogin"]);
                        TimeZoneInfo serverTimeZone = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
                        TimeZoneInfo userTimeZone = TimeZoneInfo.FindSystemTimeZoneById(GetTimeZoneNameByOffsetTime(this.GetLocation().time_zone.Replace("+", "")));
                        DateTime userLocalTime = TimeZoneInfo.ConvertTime(time1, serverTimeZone, userTimeZone);
                        Timelbl.Text = userLocalTime.ToString("dddd, MMMM d, yyyy h:mm tt");
                    }
                }
            }
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.