Sunday, November 4, 2012

Serving Websites on Local Network with IIS Express

Whenever I look through documentation, a tutorial, or blog post on any subject, I feel like Brigadier General Jack D. Ripper in Dr. Strangelove, except it's "Clarity of Essence" I'm after and not "Purity". I go to great lengths to find resources that speak to me, but sometimes when a problem needs troubleshooting it's impossible to find anything but poorly worded (and typeset) posts. But, rather than complain, I think I can contribute to some documentation on a problem whose tail I was chasing for too long.

The modern goal of embedded electronics is to create a world of "smart" devices that can upload information to and be controlled from the Cloud -- also known as the Internet to the meteorologically disinclined. Such a networked group of devices makes it possible to monitor and control our stuff from mobile devices to the benefit of our convenience and the reduction of our energy consumption. From an extreme perspective, this turns our world into a sort of video game where we can lazily monitor our current states, stats and change things with the press of a button or tilt of a joystick. I don't necessarily advocate achieving that sort of control. Certain applications of this level of control rattle my conscience (drone warfare). However, it goes without saying some applications need to be around for the good of the environment and humanity. 

Because I'm interested in building this type of networked devices, I consequently have been learning to be able to build embedded circuits and create website interfaces. My tools of choice, the two most elegant tools for doing this, are Netduino and ASP MVC. Netduino allows you to program circuits in C# and provides access to the elegant .NET Micro library. The ASP MVC framework is a great tool for quickly building websites that will offer a REST API, be backed by a database, and will benefit from templated webpages. It too relies on C#, so all logic on both sides is written in the same language.

After building a simple website with ASP MVC, I wanted to be able to send requests to it on my local network from Netduino.  To see if this was possible, I needed to first try to connect to the website from my Android phone. When I ran my website from Visual Studio, it only served the website to "localhost" on a particular port (http://localhost:<5 digit port>/). I couldn't type this URL into my phone and access the site.

I found out that Visual Studio runs the project and serves it by using IIS Express, a scaled down version of the commercial IIS server developed by Microsoft. In the project properties, there is a field to specify which URL you want to address the site. By default it is what I already mentioned, localhost. However, there is a way to make IIS Express serve the website when it receives a request for a different URL. Once this is achieved, changing what's called a URL reservation and security settings allow it to serve to computers, or phones, on the local network.

Here are the steps to follow:
  1. Find Documents/IISExpress/config/applicationhost.xml. This has a section <sites> and in it there is a section <bindings>. These list all the URLs that will represent the site. Copy the existing localhost binding and replace localhost with your IP address. Find your IP address with ipconfig in the command line and look at the top of the output for the IPv4 label.
  2. Add a URL reservation. This will grant the right for others on the network to request a URL from IIS Express and is done at the command line by typing:
    • netsh http add urlacl url=http://<your IP>:<5 digit port>/ user=everyone (Italics represents parameters to be passed.)
  3. Add a firewall rule to allow inbound requests on the port. Go to Control Panel > Windows Firewall > Advanced Settings > Inbound Rules > Add Rule. Name the rule after your site (since it will be the only one running on the chosen port). Change the scope Remote IP Address to "Local subnet". Make sure Profiles is limited to Private. Protocols and Ports should be set to TCP and the port you found in Visual Studio. 
I found that I didn't need to change the URL specified in the properties of the project in Visual Studio so long as it was localhost. In fact, it even worked when I changed it to the IP address URL. 

The problem with all other walk through posts is that they recommended the use of machine name. This never worked for me. The way I described does not require the application to be run with administrator privileges or other nonsense. 

In conclusion, I haven't created any applications that connect the Netduino and my ASP MVC project yet, but at the very least, I know I can access my service on my local network since my phone can browse the site. More to come.