Get user IP address using dns host not working on IIS - c#

I am running an application that has to get the current user IP address, the functionality seems to be working when running the app from VS, however it breaks completely when deployed on IIS, here is the code to get the user IP
public static string GetUserIP()
{
string strHostName = "";
strHostName = System.Net.Dns.GetHostName();
IPHostEntry ipEntry = System.Net.Dns.GetHostEntry(strHostName);
IPAddress[] addr = ipEntry.AddressList;
return ipEntry.AddressList.Last().ToString();
}
I have another method which uses the return value from the GetUserIP() method, here is the code
private void SaveSmsDetails(string cellNumber, string message, string userLogonName)
{
string[] userIP = IPAddressGetter.GetUserIP().Split('.');
}
Now this method is throwing a an index out of range exception, this means the GetUserIP method does not returning any value hence the Split method is falling apart, is there anything I need to do or change or perhaps something must be done on the IIS server.
Note: IIS version is 8.5.9

MSDN says: If the host name could not be found, the SocketException exception is returned with a value of 11001 (Windows Sockets error WSAHOST_NOT_FOUND). This exception can be returned if the DNS server does not respond. This exception can also be returned if the name is not an official host name or alias, or it cannot be found in the database(s) being queried.
Details here: Dns.GetHostEntry Method (String)
So, make sure that the known issues/scenarios are properly handled.
Further, try GetHostByName instead of GetHostEntry
source here

Related

Getting a client's IP address

I'm developing an ASP.NET project and I need to determine the client's IP address.
Currently, the following code on our production server
HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"].ToString();
returns an IP address that is in the same subnet as the production server's IP address (i.e., not solving my problem as it's not
the client's IP address).
However, on our test server, that same line of code returns the client's IP address (the desired result). Anyone have an idea why?
I've tried using the above line of code subbing in the following values, all of which return null or an empty string:
"HTTP_X_COMING_FROM"
"HTTP_X_FORWARDED_FOR"
"HTTP_X_FORWARDED"
"HTTP_X_REAL_IP"
"HTTP_VIA"
"HTTP_COMING_FROM"
"HTTP_FORWARDED_FOR"
"HTTP_FORWARDED"
"HTTP_FROM"
"HTTP_PROXY_CONNECTION"
"CLIENT_IP"
"FORWARDED"
As an alternative, I found the following code that does return an array of IP and contains the client's IP address (at index 4):
string strHostName = System.Net.Dns.GetHostName();
IPHostEntry ipEntry = System.Net.Dns.GetHostEntry(strHostName);
IPAddress[] addr = ipEntry.AddressList;
string ip = addr[4] != null ? addr[4].ToString() : "";
While debugging, I noticed that the IPAddress objects in addr have either (A) Address errors if it's an IPv6 address, or (B) ScopeId errors
if it's an IPv4 address. These errors don't seem to be an issue, but I'm not sure if they'll matter once in production.
Is there a better way to get the client's IP address than the way I have here?
Gets the HttpRequestBase object for the current HTTP request.
Request.UserHostAddress
you can get a client's IP address.
You can use this function to get ip address.
private string GetUserIP()
{
string ipList = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (!string.IsNullOrEmpty(ipList))
{
var ips= ipList.Split(',');
return ips[ips.Length - 1];
}
return Request.ServerVariables["REMOTE_ADDR"];
}
NOTE: HTTP_X_FORWARDED_FOR header may have multiple IP's. The correct IP is the last one.

Get detail of who is invoking webservice in C#

I have a simple webservice which returns a string of message as below:
[WebMethod]
public string GetData()
{
return "Here is your response";
}
So just to log details, is it possible to identify from which system the service has been invoked?
You can use HttpContext by:
string ip = System.Web.HttpContext.Current.Request.UserHostAddress;
And there is more usefull informations.
You can get the host address from the OperationContext.Current. The below code would do it.
RemoteEndpointMessageProperty endpoint = OperationContext.Current.IncomingMessageProperties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
string address = endpoint.Address;
This will work for both self hosted and IIS hosted services. The Address might give a IPV6 address when the network is configured with it. So you may need to resolve using Dns.GetHostEntry(address) to get the IPV4 address.

how to find the ip address of client who is login to our website or browsing our website

Here i have a small problem, that i want to find out the IP Address of the client who is accessing my website, i tried so many but all these are giving me 127.0.0.1 as IP, while i am testing in local host,
Please some one provide the code snippet and help me,
Thanks in advance,
public string GetClientIP()
{
string result = string.Empty;
string ip = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (!string.IsNullOrEmpty(ip))
{
string[] ipRange = ip.Split(',');
int le = ipRange.Length - 1;
result = ipRange[0];
}
else
{
result = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
}
return result;
}
This is to be expected, your localhost IP address will most of the time be 127.0.0.1.
As said in the comments, when you will deploy your site and remote clients access it, their actual IP will correctly be retrieved.
If you want to try locally, you can try to configure your local network so that a remote computer on the same network access your web site. There you should see the IP address of that computer (for instance: 192.168.x.x).

Difference between GetHostEntry and GetHostByName?

On MSDN it mentions GetHostByName is obsolete. The replacement is GetHostEntry. What are their difference?
It looks like GetHostEntry does a little more error checking and also supports Network Tracing
GetHostByName Decompiled:
public static IPHostEntry GetHostByName(string hostName)
{
if (hostName == null)
throw new ArgumentNullException("hostName");
Dns.s_DnsPermission.Demand();
IPAddress address;
if (IPAddress.TryParse(hostName, out address))
return Dns.GetUnresolveAnswer(address);
else
return Dns.InternalGetHostByName(hostName, false);
}
GetHostEntry Decompiled:
public static IPHostEntry GetHostEntry(string hostNameOrAddress)
{
if (Logging.On)
Logging.Enter(Logging.Sockets, "DNS", "GetHostEntry", hostNameOrAddress);
Dns.s_DnsPermission.Demand();
if (hostNameOrAddress == null)
throw new ArgumentNullException("hostNameOrAddress");
IPAddress address;
IPHostEntry ipHostEntry;
if (IPAddress.TryParse(hostNameOrAddress, out address))
{
if (((object) address).Equals((object) IPAddress.Any) || ((object) address).Equals((object) IPAddress.IPv6Any))
throw new ArgumentException(SR.GetString("net_invalid_ip_addr"), "hostNameOrAddress");
ipHostEntry = Dns.InternalGetHostByAddress(address, true);
}
else
ipHostEntry = Dns.InternalGetHostByName(hostNameOrAddress, true);
if (Logging.On)
Logging.Exit(Logging.Sockets, "DNS", "GetHostEntry", (object) ipHostEntry);
return ipHostEntry;
}
Firstly, it is important to recognize that these are wrappers of the UNIX socket library, which exposes functions inet_aton (equivalent to IPAddress.Parse), gethostbyname (wrapped by Dns.GetHostByName) and gethostbyaddr (wrapped by Dns.GetHostByAddress). Microsoft subsequently added the Dns.GetHostEntry utility function based on these.
After pondering the philosophical difference between Dns.GetHostByName and Dns.GetHostEntry, I've come to the conclusion that Microsoft decided that the primary API they expose for DNS lookups should be trying to return only actual DNS entries.
At the UNIX sockets level, gethostbyname can take either an IP address or a host name. It is explicitly documented as parsing the IP address if that's what you supply. But it is also explicitly documented as only supporting IPv4 addresses. As such, developers are encouraged to use the function getaddrinfo instead, which does a more complex look-up involving the service you want to connect to as well, and which supports address families other than IPv4.
Microsoft took a different approach in their wrapper. They still consider GetHostByName to be deprecated, but instead of tying the look-up to a services database, they decided to create a function that returns the actual physical DNS host entry you ask for. It's not enough that you perhaps supply a string with a valid address in it, if there's no DNS entry then GetHostEntry will fail, because that is its entire purpose. Thus, if you pass a host name into GetHostEntry, it performs a forward DNS lookup, and if you pass an IP address into GetHostEntry, it performs a reverse DNS lookup. Either way, the returned structure will tell you both the DNS entry name and the associated address -- but if there is no associated entry, the only thing you get back is an error.
If you're looking to handle user input that supplies a target for connection, GetHostEntry is not really suitable, because if the user types in an ad hoc IP address, it may fail to resolve it even though, since it's an IP address, you have everything you need to make a connection. GetHostByName is exactly the function you need in this case, but Microsoft have chosen to deprecate it. Given the deprecation, the idiom is going to be to replicate the "try to parse first" approach that #Faisai Mansoor showed in the decompiled GetHostByName function:
// Microsoft's internal code for GetHostByName:
if (IPAddress.TryParse(hostName, out address))
return Dns.GetUnresolveAnswer(address);
else
return Dns.InternalGetHostByName(hostName, false);
This uses internal implementation details of the Dns class, but the spirit of it is easy to replicate in your own code, e.g.:
if (!IPAddress.TryParse(userInput, out var addressToWhichToConnect))
addressToWhichToConnect = Dns.GetHostEntry(userInput).AddressList.First();

WP7 Mango - How to get an IP address for a given hostname

I need to get an IP address for a given hostname from a DnsEndPoint, and convert it to an IPEndPoint. How would I go about doing this? WP7 lacks a Dns.GetHostEntry function, so is there any way to do this without creating a Socket, sending data to the host, then receiving a ping from the host and reading the RemoteEndPoint property to get the IP address of the host?
Try using DeviceNetworkInformation.ResolveHostNameAsync in the Microsoft.Phone.Net.NetworkInformation namespace, like this:
public void DnsLookup(string hostname)
{
var endpoint = new DnsEndPoint(hostname, 0);
DeviceNetworkInformation.ResolveHostNameAsync(endpoint, OnNameResolved, null);
}
private void OnNameResolved(NameResolutionResult result)
{
IPEndPoint[] endpoints = result.IPEndPoints;
// Do something with your endpoints
}
There is no way to do this built into the framework. You could use a socket assumming that the host supports ping. It will depend on the network you are running in (I'd assume you can't control this) and the exact requirements of the application.
It may be easier to get your app to work with IP addresses and not require a hostname if all you have is an IP address.
I think Im dealing with the same problem. I also have a dynamic IP updating the dns with No-ip.
For what I know the System.Net.Dns is not available in this version of Windows Phone.
Maybe in next releases.
http://msdn.microsoft.com/en-us/library/system.net.dns.aspx
At the start of my app Im going to create a web service call to the host (to the webserver in it) asking for the IPAddress. I think I'll solve the problem in the meantime.
This could be the WCF service
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetIpAddress(string value);
}
public class Service1 : IService1
{
public string GetIpAddress()
{
// Add the proper error handling and collection matching of course
IPAddress s = Dns.GetHostAddresses("www.mysite.com")[0];
return s.ToString();
}
}
If you guys find a direct approach please let me know

Categories