How to find country from ip adress? - c#

I am using this API to find the country of a user. I am able to find the country on a web page in XML format. Here you can see XML file example. But the problem is i can not read this XML in my c# code. Here is my code
string UserIP = Request.ServerVariables["REMOTE_ADDR"].ToString();
string ApiKey = "5d3d0cdbc95df34b9db4a7b4fb754e738bce4ac914ca8909ace8d3ece39cee3b";
string Url = "http://api.ipinfodb.com/v3/ip-country/?key=" + ApiKey + "&ip=" + UserIP;
XDocument xml = XDocument.Load(Url);
But this code returns following exception on loading the xml.
System.Xml.XmlException: Data at the root level is invalid. Line 1, position 1.
Please describe the exact method to read this XML.

I'll say that it isn't an XML but simply a string subdivided by ;:
By giving an impossible IP address we can see that it's so composed:
OK;;74.125.45.100;US;UNITED STATES
ERROR;Invalid IP address.;127.0.0.1.1;;
OK/ERROR
If ERROR, complete ERROR message
IP Address
Abbreviation of country
Country name
This code should do:
string userIP = "127.0.0.1";
string apiKey = "5d3d0cdbc95df34b9db4a7b4fb754e738bce4ac914ca8909ace8d3ece39cee3b";
string url = "http://api.ipinfodb.com/v3/ip-country/?key=" + apiKey + "&ip=" + userIP;
WebRequest request = WebRequest.Create(url);
using (var response = (HttpWebResponse)request.GetResponse())
{
// We try to use the "correct" charset
Encoding encoding = response.CharacterSet != null ? Encoding.GetEncoding(response.CharacterSet) : null;
using (var sr = encoding != null ? new StreamReader(response.GetResponseStream(), encoding) :
new StreamReader(response.GetResponseStream(), true))
{
var response2 = sr.ReadToEnd();
var parts = response2.Split(';');
if (parts.Length != 5)
{
throw new Exception();
}
string okError = parts[0];
string message = parts[1];
string ip = parts[2];
string code = parts[3];
string country = parts[4];
}
}

Here is what I'd do:
Using a HTTP transfer, query the site, and buffer the results
Convert it into a String
Use a splitting algorithm on it to make into an array.
Check if the 0th element of the array equals 'OK'
If not, bail out.
If so, check the third and fourth elements for country code, and country name respectively.

from the IP Location XML API Documentation: API Parameter format, required = false, default = raw, values = raw, xml, json. so I have tested it and string Url = "http://api.ipinfodb.com/v3/ip-country/?key=" + ApiKey + "&ip=" + UserIP + "&format=xml" gives a parsable xml result.

Related

C# Print a specific string fom a website using HtmlAgilityPack

I need to get some text from a website we are using to get our data from. I finally found how, using HtmlAgilityPack and finding the Xpath I'm able to print out some text from the website.
But when I try to print the date and kind, which is coded like this:
<span class="span-line-break">zaterdag 05 december 2020</span> //Date
<span class="afvaldescr">Papier en karton</span> //Kind
I can't reach these two strings using my current code:
public string Postalcode = "6093DK";
public string Number = "2";
public string Add = "";
string url = "https://mijnafvalwijzer.nl/nl/" + Postalcode + "/" + Number + "/" + Add;
var web = new HtmlAgilityPack.HtmlWeb();
HtmlDocument doc = web.Load(url);
string when = doc.DocumentNode.SelectNodes("//*[#id=\"december-2020\"]/div/table[1]/tbody/tr/td[1]/a/p/span[1]")[0].InnerText;
string what = doc.DocumentNode.SelectNodes("//*[#id=\"december-2020\"]/div/table[1]/tbody/tr/td[1]/a/p/span[2]")[0].InnerText;
textBox1.Text = when;
textBox2.Text = what;
I figured that because the text is in a class I can not reach it.
Can someone help me find a more specific route to these strings?
The website is a Dutch garbadge calendar, don't mind it.
Browser inserts tbody for table element although it is not present in html. So here I just removed tbody from your XPath. In Chrome you can use network tab for viewing original response
string when = doc.DocumentNode.SelectNodes("//*[#id=\"december-2020\"]/div/table[1]/tr/td[1]/a/p/span[1]")[0].InnerText;
string what = doc.DocumentNode.SelectNodes("//*[#id=\"december-2020\"]/div/table[1]/tr/td[1]/a/p/span[2]")[0].InnerText;
You can also use shortened version of XPath using "//" and class selectors
string when = doc.DocumentNode.SelectNodes("//*[#id=\"december-2020\"]//table[1]//span[#class=\"span-line-break\"]")[0].InnerText;
string what = doc.DocumentNode.SelectNodes("//*[#id=\"december-2020\"]//table[1]//span[#class=\"afvaldescr\"]")[0].InnerText;

How to retrieve characters before and after a forward slash

I have this string which comes from the datareader: http://win-167nve0l50/dev/dev/new/1st Account
I want the get the file name, which is "1st Account"
and the list name, which is "new" and the list address which is "http://win-167nve0l50/dev/dev/". This is the code I am using:
How do I retrieve the site address and the list name.
//getting the file URL from the data reader
string fileURL = dataReader["File URL"].ToString();
//getting the list address/path
string listAdd = fileURL.Substring(fileURL.IndexOf("/") + 1);
//getting the file name
string fileName = fileURL.Substring(fileURL.LastIndexOf("/") + 1);
You can get all sorts of info easily using the Uri Class
var uri = new Uri(dataReader["File URL"].ToString());
then you can get various bits from the Uri object eg.
Uri.Authority - Gets the Domain Name System (DNS) host name or IP address and the port number for a server.
Uri.Host - Gets the host component of this instance
Uri.GetLeftPart() - Gets the specified portion of a Uri instance.
If dealing with Uri, use the according class ...
Uri u = new Uri(dataReader["File URL"].ToString());
... and access the desired parts of the path by Segments array
string listAdd = u.Segments[3]; // remove trailing '/' if needed
string fileName = u.Segments[4];
... or in case you need to make sure to handle arbitrary path length
string listAdd = u.Segments[u.Segments.Length - 2];
string fileName = u.Segments[u.Segments.Length - 1];
You should use the Uri class
It's main purpose is to handle composed resource strings.
You can use:
Uri.Host to obtain the host address string
PathAndQuery to getthe absolute path of the file on the server and the query information sent with the request
All the properties here
You can also do it with Regex:
string str = "http://win-167nve0l50/dev/dev/new/1st Account";
Regex reg = new Regex("^(?<address>.*)\\/(?<list>[^\\/]*)\\/(?<file>.*)$");
var match = reg.Match(str);
if (match.Success)
{
string address = match.Groups["address"].Value;
string list = match.Groups["list"].Value;
string file = match.Groups["file"].Value;
}

Special chars in query string

I am passing a query string parameter containing file name.
default.aspx?file=Fame+ adlabs.xml (Fame+ adlabs.xml is the actual file name on server). The file name has "+" & also blank spaces.
When I check for file name from query string as follows:
var fileName = Request.QueryString["file"];
The variable filename does not have a "+" in it. It reads as "Fame adlabs.xml" & hence I get a file not found exception. I cannot rename the xml files. Can someone please guide me into right direction.
Thanks
If you are trying to do it at the server in C#:
String FileName = "default.aspx?";
String FullURL = FileName + HttpUtility.UrlEncode("Fame + adlabs.xml");
String Decoded = HttpUtility.UrlDecode(FullURL);
You should URL encode into your javascript before sending it :
var name = "Fame+ adlabs.xml";
var url = "default.aspx?file=" + encodeURIComponent(name);
Pay attention that following char won't work : ~!*()'

Add a directory name to a URL address using C#

I have a textbox where users can paste a URL address. I want to add a directory name to the URL before saving it in the database.
<asp:TextBox ID="urlTextbox" runat="server"></asp:TextBox>
Code behind
TextBox url = urlTextbox as TextBox;
string urlString = urlTextbox.Text;
Let's say the urlString = "mydomain.com/123456". I want to replace it with "mydomain.com/directory/123456". mydomain.com/directory is the same for all the URLs. The last part "123456" changes only.
Thank you
I'd suggest seeing if your needs are met with the UriBuilder class.
UriBuilder url = new UriBuilder(urlTextbox.Text);
Now you can use the various properties to change your url.
string formattedUrl = string.Format("{0}://{1}/directory/{2}", url.Scheme, url.Host, url.Path);
A better idea is to adjust the URL with another / same UriBuilder as noted by Jared.
UriBuilder url = new UriBuilder(urlTextbox.Text);
url.Path = string.Format("directory/{0}", url.Path);
Use this object as a Uri by simply doing this
Uri formattedUrl = url.Uri;
Or convert to a string if needed.
string formattedUrl = url.ToString();
You can also use Uri.TryParse(...) to verify if it's a valid URL being entered into the text box.
To get the individual query parameters, you can look at the Uri object.
UriBuilder url = new UriBuilder("mydomain.com/123456?qs=aaa&bg=bbb&pg=ccc");
url.Path = string.Format("directory/{0}", url.Path);
Uri formattedUrl = url.Uri;
string queryString = formattedUrl.Query;
// parse the query into a dictionary
var parameters = HttpUtility.ParseQueryString(queryString);
// get your parameters
string qs = parameters.Get("qs");
string bg = parameters.Get("bg");
string pg = parameters.Get("pg");
You can use string functions Split and Join to achieve your result. An example code is shown below
List<string> parts = urlString.Split(new char[] { '/'}).ToList();
parts.Insert(parts.Count - 1, "directory");
urlString = string.Join("/", parts);
This is one way of doing. Split the urlString using .split() function.
string[] parts = urlString.Split('/');
parts[parts.Length-1] will have that number. Append it to the string you want.
I'd do something like this:
//Assuming the address in urlString has the format mydomain.com/123456
string[] urlParts = urlString.Split('/');
string directory = "directory";
string finalUrl = urlParts[0] + "/" + directory + "/" + urlParts[1];
Be careful if the address has other "/" characters, like if preceded by http:// or something like that.
Hope it helps.
Simply use concatenation:
save in a temporary string
temp="mydomain.com/directory/"
and save the changing part in another string like
temp2="123456"
now concatenate both temp1 and temp2 like below.
urlString=temp1+temp2;

base64 decode null reference excpetion on URL

So i have this code on my cs page that takes decodes a key from my Url string. The key is "Reauth_URL" and its a link that is decoded in base64 to UTF8.
////base 64 decoding for Reauth_URL key in URL query string
string encodedString = Convert.ToString(HttpContext.Current.Request.Params["Reauth_URL"]).Trim(')');
byte[] data = Convert.FromBase64String(encodedString);
string decodedString = Encoding.UTF8.GetString(data);
I'm trying to use decodedString but i keep on getting a null refence exception but i can see that the key and value are there.
once i can return the string value id like to ba able to send it into a hyperlink that's on my aspx page.
the encoded url is set up from IronPort which allows a user to lg in as differnt user if they've been blocked from a website. so this reauth_url key in the query string allows them to log in as different user. by the reauth_url needs to be decoded and linked to the hyperlink. I know the key and value is there but i cant get by this null exception, and when i say i know they are there obviously i don't mean in the code above, ive had to split the url query by ? and & and print it out somewhere else and they exist. The code below is used earlier and the key and value i need is there.
string currentUrl = HttpContext.Current.Request.Url.Query;
txtBlockedUrl.Visible = true;
string [] result = currentUrl.Split(new Char[]{'?','&'});
foreach (string r in result)
{
txtBlockedUrl.Text += HttpUtility.UrlDecode(r) + "\n";
}
div style="font-size: medium">
LogIn as Different User
</div>
If HttpContext.Current.Request.Params["Reauth_URL"] is null, Convert.ToString will throw a null reference exception.
Please note that the Params indexer will return null when "Reauth_URL" is not available.
So you have to check first if it exists: (what if the url does not provide it?)
string value = HttpContext.Current.Request.Params["Reauth_URL"];
if (value!=null) {
string encodedString = Convert.ToString(HttpContext.Current.Request.Params["Reauth_URL"]).Trim(')');
//...
Ended Up doing this....
//splitting url string for textbox using name value collection
NameValueCollection collection = new NameValueCollection();
string currentUrl = HttpContext.Current.Request.Url.Query;
string [] result = currentUrl.Split('&');
foreach (string r in result)
{
string[] parts = HttpUtility.UrlDecode(r).Split('=');
if (parts.Length > 0)
{
string key = parts[0].Trim(new char[] { '?', ' ' });
string val = parts[1].Trim();
collection.Add(key, val);
}
}

Categories