Sunday, June 16, 2013

How to Connect to Local Web Services from the Windows Phone 8 Emulator

In this post I want to share some tips on how to enable locally hosted web services connectivity, so you can connect to them from the Windows Phone 8 emulator or any devices in your network.

The best way to demonstrate this is with a sample web service and a WP8 applications. For this post I’ll be using a File Upload MVC Service and a File Upload WP8 app. Check the articles on my blog post for implementation details and source code.

The code required for the service and the mobile app is actually quite straight forward. On the other hand, being able to connect to your local service from your emulator or device, and test locally, is actually tricky. This gave me quite a few hours of wall banging since although I had some code in place, I could not figure out how to test it. My good colleague Herber Madrigal gave me a hand, and put together a prove of concept for me.

It turned out, that there are a couple vital steps your need to take to be able to run your service so the emulator and devices can connect and use the service based on the local machine IP.

In WP8, the emulator configures itself as a separate device on the network, and so, it can’t connect to the development computer as localhost. Effectively, it acts as a separate device in your network.

Before you can connect successfully from the emulator or a device in the network, you will have to do two changes:

Configure the local web service and web server to accept connections from other devices on the network.

You have to configure the service in the WP8 app to connect to the service by using the IP address of the development computer on which the service is running.

Let’s start with the web service. You can use WCF, Web API or ASP.NET MVC (or any other web services technology for that matter), as long as you can provide an endpoint that accepts a HTTP request using multipart form data. I have previously published a post on how to implement the upload service. Check it out for details and step-by-step instructions. You can also download the sample project here.

Run the project and go to the /fileupload page. You should see the page displaying correctly, indicating that the request was received, but no file was sent.

If you want to test the upload, you can use a tool like Fiddler to emulate the file upload request, as I showed in my previous post.

Ok. Now that we have the service running, you need to do a couple of configuration tricks to allow the service to be reached from the Windows Phone emulator or device. You need to bind your application to your public IP address, so it can be reached by another machine, or in this case another virtual machine. Once you do that, you need to configure the Windows firewall to allow incoming connections, which are most commonly locked by default.

Remember that the Windows Phone emulator configures itself to run as a separate device on the network, so it can’t, by default, reach localhost!

At this point, you should be able to run the web service and on the browser, go to the /fileupload using your IP address and port instead oflocalhost. However, that works only from the browser.

Note: you might not be able to reach out the endpoint with your IP address. If that is the case, completing the following steps, and re-running the web service should fix it.

Allow Incoming Connections

If you try to reach the endpoint on your browser using the IP address, you will most likely get a Bad Request or Service Unavailable response, since up to this point the firewall is not allowing incoming connections.

Start a command prompt with administrative privileges.

Run the following command making sure to include your IP address and the correct app port:netsh http add urlacl url=http://youripaddress:yourappport/ user=everyoneThis just tells http.sys that it’s ok to talk to this url.

Add a rule in the Windows Firewall, allowing incoming connections to your app port for computers on your local subnet. To do so, run the following command including the correct portnetsh advfirewall firewall add rule name="IISExpressWeb" dir=in protocol=tcp localport=yourappport profile=private remoteip=localsubnet action=allow

If you open the Windows Firewall manager, you should be able to see the new rule added. You can change or delete the rule from here easily.

Now, you can go back to the service project in Visual Studio and run the project again. Now you should be able to reach the /test or /fileupload endpoint using your IP address.

The easiest way to test that the web service is now allowing network devices to connect is to go to the /fileupload page from the Windows Phone emulator or the device browser. If you are able to reach the page (and also debug the incoming request from Visual Studio) you are good to go.

You can easily test the Windows Firewall rule by going into the Firewall’s manager and disabling the rule. If after doing it, you refresh the page on the emulator’s browser, it won’t work.

To summarize, remember that you can actually enable your locally hosted web services to be reached by local apps running on the Windows Phone 8 emulator or any other devices in your network. To do this, you will need to create an IP binding on your web server configuration to allow the apps to use the local machine’s IP address instead of localhost. Then you need to create a rule to allow inbound HTTP requests to go through the Windows Firewall. Make sure to check the IP address of your local machine when testing to make sure is the right one (it can change if your provider uses dynamic IP assignment).