I have an android application that's supposed to send a request to a simple HelloWorld C# webservice I made on ServiceStack but I am not able to connect. My application crashes when I try to connect. Here is my code on Eclipse, trying to access the ServiceStack service:
String base = "http://192.168.1.7:62938/json/reply/Hello?Name=";
String str = editTextField.getText().toString();
StringBuilder url = new StringBuilder(base + str);
String result = "";
HttpClient hc = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url.toString());
HttpResponse r = hc.execute(httpget);
int status = r.getStatusLine().getStatusCode();
if (status == 200) {
HttpEntity e = r.getEntity();
String data = EntityUtils.toString(e);
JSONObject o = new JSONObject(data);
result= o.getString("result");
}
My C# service code for ServiceStack:
//Request DTO
public class Hello
{
public string Name { get; set; }
}
//Response DTO
public class HelloResponse
{
public string Result { get; set; }
public ResponseStatus ResponseStatus { get; set; }
}
//Can be called via any endpoint or format, see: //http://mono.servicestack.net/ServiceStack.Hello/
public class HelloService : Service
{
public object Any(Hello request)
{
return new HelloResponse { Result = "Helloooo, " + request.Name };
}
}
My service works fine on my laptop when I go to localhost:62938/json/reply/Hello?Name="arbitraryName"
but it does not work when I try to replace localhost with my laptop's ip address and access the service from an android device. It also does not work if I replace localhost with my IP address and try it on my browser on my laptop. Note: I want to make it work from a real android device, not an emulator.
Is there something different with ServiceStack services where I cannot access it normally from another device? I have already tried opening port 62938 and it did not work.
I appreciate any guidance. Thank you.
It also does not work if I replace localhost with my IP address and try it on my browser on my laptop.
If you have tried accessing the ServiceStack service through the local IP address of 192.168.1.7 in your computer's web browser and it is also unreachable, then the issue isn't isolated to Android.
This is issue is likely the result of one or more of these problems:
Check you are listening on the correct IPs:
Your ServiceStack service isn't configured to listen for requests on any other interfaces other than localhost. Select your relevant hosting option:
Self Hosting:
This can happen if you are self hosting and you have configure the app host to start with appHost.Start("http://localhost:62938/");. You would need to replace localhost with a + symbol to have it listen on all local addresses.
IIS Express:
By default IIS Express is used by Visual Studio during development, unless manually configured to use IIS, and is restricted to localhost requests only. You should see this answer as to how to configure IIS Express to allow non-local access as well.
This tutorial by Scott Hanselman is also very good, and provides great step-by-step instructions for configuring IIS Express.
IIS:
You can confirm the IP addresses that you server is configure to listen on by following these instructions. They provide instructions for both IIS6 and IIS7+.
Firewall:
Your computer may have a firewall preventing you accessing that port, or accepting outside traffic. Note your firewall may be built into antivirus software you run. You should add an exception rule for http traffic on port 62938.
Correct IP:
You are trying to access on 192.168.1.7. You should confirm that IP address is in fact correct. Most home networks are configured to provide a dynamic IP address by the network router. The IP address may have changed since you last checked it. You should try running a ping to the IP from your development machine.
Until you can successfully access the service through your web browser on your development machine, at the local network IP starting 192.168.1.X then I wouldn't attempt to access from Android. It's not an Android issue if other systems can't access your service also.
I hope that helps. If you provide more information about your specific environment, I may be able to provide more specific instructions. If I had to guess, I would say IIS Express issue.
Edit:
Now that you can access the service in the web browser of your android device but not in the application, we know the service is remotely accessible. This means your connectivity issue is isolated now to your application. The first thing I would check, is that your application has permission to make network requests. In your AndroidManifest.xml you need to ensure that android.permission.INTERNET is included
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
If you have that permission then you should be able to make the request successfully. If it continues to fail, then the reason need to be diagnosed from the exception that is causing the application to crash. In which case you should wrap the data request in a try { ... } catch(Exception exception) { } and log the exception.
As the Android emulator is considered to be running on a different device, to refer to the loopback IP (127.0.0.1) on our local development machine we need to use the special 10.0.2.2 alias.
Other special device IP's can be found in Andorid's documentation.
Related
I am writing a blazor server side application (.NET6) for my homeautomation and let it run on iis on a home server.
If I run the following code on my local machine in IIS Express everything works fine.
string _urlForecast = "https://api.openweathermap.org/data/2.5/forecast?id=...";
Uri myUri = new Uri(_urlForecast, UriKind.Absolute);
HttpResponseMessage response = await HttpClient.GetAsync(myUri);
var data = await response.Content.ReadAsStringAsync()
If I deploy it to my local homeserver and run it I get the following error:
System.Net.Http.HttpRequestException: No such host is known. (api.openweathermap.org:443)
My 'homeserver' is also running windows 10 and is in the same network as my dev pc.
It is in the same ip range and has the same DNS settings on the network adapter.
I also tried it with turned off firewall with the same result.
I am injecting the httpClient with DI but also tried without DI.
I tried to use http://api... and https://api... as my application is also available in the internal network via https. Unfortunately I have don't have any experience with Http requests and would be thankful if anybody could help.
I am currently using Httpclient and I can successfully gather my data with a specific network/internet-connection at the place that has the data.
However when I try to gather the data at home with another internet-connection I receive an "NameResolutionFailure" error.
My goal is to be able to reach the data from any type of connection but I am not sure what I am quite missing here. (I am also new in this area).
This is the code that I use when I talk to the db:
string dataurl = "my-url-here";
var http = new HttpClientHandler()
{
Credentials = new NetworkCredential("user", "password", "domain"),
};
var httpClient = new HttpClient(http);
try
{
var result = await httpClient.GetStringAsync(dataurl);
System.Diagnostics.Debug.WriteLine(result);
}
catch (HttpRequestException ex)
{
if (ex.GetBaseException() != null)
{
System.Diagnostics.Debug.WriteLine(ex.GetBaseException().Message); //this is where i recieve the NameResolutionFailure error
}
else
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}
How come I can only reach the data when I am on a certain network and not with every network? Am I missing code or is there something else in play here?
Appreciate every help, tips, code-examples i can get!
The problem is likely to be in the string dataurl = "my-url-here"; and where that's accessible from. There are likely to be two obstacles:
Name resolution
Network Access
While your error message only mentions Name resolution, I'm guessing you'll need to do something about network access as well.
Name resolution (or DNS) is about translating a host name into an I.P. address.
When you're on a work network, there'll be a name resolution service that resolves local computer names to I.P. addresses on the network. Normally these local computer names are not visible to public DNS servers. If you connect your device to a different network (e.g. a mobile network), it uses the public DNS servers, which know nothing about the local domain named computers.
For example MyServer might resolve on your local network because it's part of your local domain, and the local network infrastructure will sort that out. MyServer.MyCompany.com is usually similar, as by default machines names aren't exposed externally.
For a mobile application, you're going to need a public domain name. Something like MyServer.MyDomain.com (or www.google.com is the same thing, essential). A public DNS server translates this name to an I.P. address.
This is probably where the problem you're experiencing is occurring. You're probably using a local host name, that the public DNS servers don't know about.
If you're working for an organisation they may already have a domain, or you may need to purchase a domain for your application.
In the meantime you could look at one of the dynamic DNS solutions that may allow you to progress for development purposes.
For my Xamarin app, I use the name of the local machine when I'm developing, and the mobile device is on the same network.
If I'm not on the same network, I have a VPN that I can use. This connects into the work network as if I'm on the same network. If I'm developing at home and both devices are on my home network, I use the I.P. address of my development box, because I haven't made local DNS work on my home wifi.
When we go to release we use a public URL, like api.MyApp.com - which public DNS points to our prod server.
Network Access might be a thing that you need to deal with too.
A major part of a Network Engineer's job is to keep the hackers out. When your mobile device is on the same network as the server (i.e. when it's working for you), this isn't a problem because because mostly networks are configured so that two devices on the same network can see each other. It sounds like this is the sort of network you have, if your app can see your server on one connection.
But if you're needing to connect to your server from a mobile network, you need a way to tell your network router to forward specific traffic from the internet to your server.
This gets complicated, but for development purposes, strategies I've seen work are:
A VPN - we have a VPN that I fire up on the mobile device, enter my work network credentials, and then I can access my development box as if I'm on the same network
Virtual server / port forwarding - if you're at home, you can probably configure your modem to forward a particular port to your development box. Every modem is different, so you'd have to search up instructions for your particular one.
Network Engineer - if you're in a corporate, and want traffic from outside to get to a server that you're managing (and don't have a VPN), you probably need to talk to your networks department. Good luck.
I'm creating a web application where I need a functionality that if someone client log in to my website the client's public IP address must be logged. I have some javascript to do this but some of my pal not agree to use a javascript library reason they don't trust it. Such as http://l2.io/ip.js?var=myip as mentioned here
So we need all of it as server side code. So i found few more code in this
link but unfortunately I'm not getting the expected result (it only returns local hosts IP). Could anyone help me to solve this please.
I have tried the bellow code
string VisitorsIPAddr = string.Empty;
if (HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null)
{
VisitorsIPAddr = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();
}
else if (HttpContext.Current.Request.UserHostAddress.Length != 0)
{
VisitorsIPAddr = HttpContext.Current.Request.UserHostAddress;
}
but this is not providing me the public IP. Do I need to deploy it or something.
HttpContext.Current.Request.UserHostAddress
This should get the public IP address of a client
EDIT
So you're after the IP address of your own machine as the rest of the world sees it??
This only really matters if you're hosting in on lets say an Intranet where the clients will be on the same network and thats the only address you will get if you use HttpContext.Current.Request.UserHostAddress. You will need to use a lookup api or something in this case. But then you'd know the external IP of your network!
If this is to be hosted on the internet then HttpContext.Current.Request.UserHostAddress will work just fine as every client will be displaying it's external IP.
It's showing 127.0.0.1 I'm guessing because you're testing on your local machine and this will be it's loopback address.
Hope this helps
A particular rest service I am calling in a Windows Store app wants the IP address of the calling computer as a parameter. None of the tried and true examples using System.Net or System.Net.NetworkInformation compile in a Store app.
What is the magical combination of types and methods available in a windows store app that will get to the local machine's IP address? I feel like it is probably obvious but I am not seeing it!
You will have to contact an external server. Even if the platform supplies an API to retrieve the network address, the host could still be located behind a proxy or a NAT (and you will see something like 192.168.1.4, instead of your external IP address).
Just perform an HTTP request towards services like http://ifconfig.me/ or http://whatismyip.com/ and parse the IP.
Local network IP address:
foreach (HostName localHostName in NetworkInformation.GetHostNames())
{
if (localHostName.IPInformation != null)
{
if (localHostName.Type == HostNameType.Ipv4)
{
// E.g.: 192.168.1.108
Debug.WriteLine(localHostName);
}
}
}
My GPRS modem has got a sim card. it can connect Web. Web service give it a ip number. i need it. like that: http://www.your-ip-address.com/
How can i do that C#?
You can use the static method WebClient.DownloadString(url) to read your external IP address from any web service providing such data:
string ip = System.Net.WebClient.DownloadString("http://whatismyip.org/");
If you are going to use this in a production environment, better make sure that the URL you are pointing to, is guaranteed to stay around for the entire lifespan of your application. The best way is probably to host the web service yourself.
Also, you should add some error checking around this code, as it will fail if the internet connection or the web service is unavailable.
You can get a list of your IP addresses via DNS using the following code:
var name = Dns.GetHostName();
var entry = Dns.GetHostEntry(name);
foreach (var address in entry.AddressList) {
Console.WriteLine(address);
}
If you want the IP address as a property of the hardware, you can use the System.Management.ManagementClass with the name Win32_NetworkAdapterConfiguration. See http://msdn.microsoft.com/en-us/library/system.management.managementclass.aspx for details.
You can create a WebRequest to http://whatismyip.com/automation/n09230945.asp which houses only your IP address
Start here