Starting from Visual Studio 2012 the good ol' Cassini Web Server has been replaced by IIS Express. While Microsoft spent quite an amount of words describing the benefits brought by this not-so-minor change, the strictness of the security policies featured by the newcomer raised more than an issue between those accustomed to the old environment: the new Property window doesn't allow devs to change the local hostname/folder or to assign a custom TCP port anymore, which can be crippling in most scenarios. Another serious issue is due to the fact that IIS Express, unlike Cassini, doesn't natively accept external request, meaning that no network-connected client can be used to debug the website anymore.
HTTP Error 503. The service is unavailable.
We're talking about a serious issues here, expecially in times like this where everything is about responsive, mobile-friendly, postback-free web-based stuff which almost always need to be tested on many different devices.
The three reasons preventing IIS Express to accept external requests are:
- Its configuration XML file, where Visual Studio saves the (auto-generated) web application settings once we run it in Debug or Release mode the very first time.
- The security restrictions (ACL settings) on the HTTP.SYS component, who doesn't allow a non-elevated application - like Visual Studio executed like the current user - to handle network traffic.
- The default Windows Firewall (or any other firewall installed) settings, hardly allowing an arbitrary set TCP port to accept outcoming calls.
Let's see what we can do to go through all these problems:
- Be sure you don't ave any open Visual Studio instance.
- Open the file %userprofile%\Documenti\IISExpress\config\applicationhost.config , being %userprofile% your user folder - like C:\Users\YourUsername\.
- Look for the entry corresponding to the web application we want to modify and change its binding element in the following way:
<binding protocol="http" bindingInformation="*:<port>:*" /> All we need to do there is to replace a couple of localhost with *, leaving the automatically assigned <port> as it is. If you really need to change that port, replace it with another valid, free TCP port (like 8080) and perform the following step. Otherwise, skip it and go to the step next to it.
- If you changed the automatically assigned TCP port you also need to open your web application project (.csproj) and solution (.sln) files and ensure there are no references to the previous port: they can be there or not depending on your choosen project type (Web Application, MVC App, Web Site, etc.). If that's the case, replace the old port with the new one.
- Open a Command Prompt (with Administrator permissions) and type the following:
netsh http add urlacl url=http://*:<port>/ user=everyone Putting the application TCP port in place of <port>. If you get an error messae (1789) it means that the Everyone user group is not present on your system, something who can occur in some Windows localizations. If that's the case, just replace everyone with the corresponding user group name. Instead than doing this step you could also try and execute Visual Studio with administrator permissions.
- Open Windows Firewall advanced configuration panel and add an inbound rule to enable the inbound traffic for the application IISExpress.exe OR for the TCP port used by your web application. If you disabled it for another product, do the same with it. If you ain't using any - are you sure? - you can either take the chance to fill the void and then perform the above or just skip this step.
Once you did this you can launch Visual Studio and run your application in Debug or Release mode: you should be able to access it from any external, network-connected device using the following web address:
Visual Studio 2015 Update
As pointed out by Zachary Pittman (many thanks to him for reporting this), if you're using the IIS Express bundled with Visual Studio 2015, you will find the relevant applicationhost.config file within a /.vs/ subdirectory within your project root folder. However, whenever you've unsure about the path, you can always right-click to the IIS Express icon in the system tray: from there, > Show all applications, select your site and look for the config file location.
Let's just say it: IIS Express, with all its flaws and missing configuration features, is far from being the best web development server available. Anyone looking for a more robust, versatile solution will probably like to switch to something like IIS 7.5 (or above). The main issue there is due to the fact that in order to use IIS togheter with Visual Studio you could be forced to launch it with administrator permissions to avoid the following error message:
This happens because Visual Studio needs to have access to the IIS metabase, a priviledge reserved to the Network Administrators group.
UPDATE: If you don't feel like executing Visual Studio with administrative priviledges you can use this neat workaround to permanently grant the IIS Metabase folder permissions to the current user in a quick and easy way.
What else can we say? Happy (so to speak) coding!
EDIT: If you want to dive deeper into IIS Express mechanics and understand the reasons that moved Microsoft to make it become the successor of Cassini I would suggest you to read this excellent (despite its age) post by Scott Hanselman. Have a good reading!
16 Comments on “IIS Express: allow external requests from remote clients & devices”
I bumped into the same issue a while ago. But since I’m also a Node.js developer, I wrote a simple command-line utility to proxy the external traffic to IIS Express.
It’s as simply as running “iisexpress-proxy 51123 to 3000” in the command line and you can simply access your app on host:3000. No need to play around the ACL or crazy XML config files ;-)
Have a look at https://github.com/icflorescu/iisexpress-proxy.
That’s a great idea, and I thank you for sharing this! Nonetheless that’s a whole different approach, as it involves installing and using third-party tool(s) such as Node.js. I’m not saying it’s not viable, it’s just that I prefer tweaking over installing until I still can :) Nice work anyway, keep it up!
Yeah, I know, and that’s why I was initially surprised to learn how many people started to use iisexpress-proxy after I mentioned it in a stackoverflow reply. It’s probably because more and more .NET developers started to use gulp, grunt, browserify, Angular.js, etc. since Microsoft kind of embraced open-source :-).
I guess many C#/.NET developers already have Node.js installed on their machines, so…
That’s for sure, since now Node & NPM are shipped alongside Visual Studio 2015 as well: but you could also replace IIS Express with IIS 7+ and solve a number of problems without resorting to mix-in with Node (since VS2008 at least) or even switch entirely to Node (from VS2015). Anyway, being a Gulp/Node user myself, I feel that tweaking around with some XML/ACL settings is not much different than messing around with module scripting, so I honestly would either take IIS Express and tweak it *OR* switching to IIS, Node.js or other alternatives. That’s just my way of seeing things anyway, not meant to influence anyone :)
I love you! Thank you!
Feels nice to be loved :-P
Great article. Just wanted to note a change with the IIS Express that comes bundled with the Visual Studio 2015 install. The applicationhost.config file lives within each project folder. You can view the path by examining IIS Express from the system tray > Show all applications. Select your site and you will see the config file lives in a .vs folder at your root project folder.
Added your suggestion to the post: thanks!
Dude, thanks for the utility tool you wrote. You just saved me a load of time by avoiding playing around with config files and different settings up and down. I can now focus on other areas of the application development. :)
Great post, probably the most comprehensive one I have come across on this topic. I used to have a working setup for this which I used in conjunction with ngrok however on returning to this now I seem to find it impossible to access my IIS Express instance from anything but localhost.
My applicationhost.config site definition has the following binding:
I’ve added the url reservation as follows:
netsh http add urlacl url=http://*:18706/ user=everyone
I’ve created the firewall rules and even disabled my Firewall but still all I get is failed connection messages in my browsers. Strangely I cannot even access it via http://127.0.0.1:18706/ but can via http://localhost:18706/
the first thing I would do is to check the following SO answer:
It seems like the OP solved his issue (the same as yours) by changing the http port configurations in Visual Studio. Right after that, I would try again – maybe that will fix the other issue you’re having as well.
Let me know,
Another, simpler option is to use our Visual Studio extension called Conveyor, it doesn’t play with any config settings. https://marketplace.visualstudio.com/items?itemName=vs-publisher-1448185.ConveyorbyKeyoti
I’m using VS 2015 Update 1. When I do exact as this post, It creates another set of “site” elements with localhost. What works for me was adding another binding with ‘*’ or IP address without changing existing binding (have both binding elements).
under applicationhost.config file i set the binding url
then under program.cs i set as
var host = new WebHostBuilder() .UseUrls(“http://localhost:54704;
using netsh from admin command prompt set acl
swithched off the firewall
set inbound rule on tcp port for 54704
still unable to call from gennymotion browser as http:10.0.3.2:54704/api/Admin
gives http error 503 service is unavailable.
Please help, cracking this problem from 2 weeks(in vs2017,runs on localhst as http://localhost:54704/api/Admin)