Step 1: binding in the configuration
In the IIS Express configuration file, in the site's <bindings> section, a binding for the local IP address is added next to the existing localhost binding:
<bindings> <binding protocol="http" bindingInformation="*:10080:localhost" /> <binding protocol="http" bindingInformation="*:10080:192.168.1.2" /> </bindings>
Where the file is located depends on how IIS Express is started:
- when IIS Express runs on its own or from Visual Studio older than 2015:
C:\Users\{your username}\Documents\IISExpress\config\applicationhost.config; - Visual Studio 2015 and 2017:
.vs\config\applicationhost.configin the solution folder; - Visual Studio 2019 and newer:
.vs\{solution name}\config\applicationhost.configin the solution folder.
The port (10080 here) should be the same as in the project's existing binding.
Step 2: reserving the URL
Windows lets a program without administrator privileges listen on an address other than localhost only if that address has been reserved. The command is run in a command prompt opened as administrator:
netsh http add urlacl url=http://localhost:10080/ user=everyone netsh http add urlacl url=http://192.168.1.2:10080/ user=everyone
The group name everyone only works on the English version of Windows; on a localized version the group has a different name and the command fails. It is safer to specify the group by its SID, which works in any system language:
netsh http add urlacl url=http://192.168.1.2:10080/ sddl=D:(A;;GX;;;WD)
Step 3: a firewall rule
On the computer running the application, incoming connections on that port have to be allowed. This can be done in the Windows Defender Firewall settings or with a single command, also as administrator:
netsh advfirewall firewall add rule name="IIS Express 10080" dir=in action=allow protocol=TCP localport=10080
Checking and removing
After the changes, stop IIS Express (the icon in the system tray) and start the project again. The site is then available both at http://localhost:10080/ and at http://192.168.1.2:10080/, including from other devices on the same network. If the error Bad Request - Invalid Hostname appears, IIS Express did not read the binding from step 1, most often because the wrong applicationhost.config was edited.
When access through the IP address is no longer needed, the reservation and the firewall rule are removed:
netsh http delete urlacl url=http://192.168.1.2:10080/ netsh advfirewall firewall delete rule name="IIS Express 10080"
When is this useful?
Access through a local IP address is useful when an application needs to be tried on a mobile phone or tablet, when several team members test the same application from their own computers, or when another device on the network needs to call an API that is still in development. More about the server itself can be found in Microsoft's IIS Express overview.
Newer ASP.NET Core applications can use the built-in Kestrel server instead of IIS Express. For them it is enough to set the address in applicationUrl in launchSettings.json to http://0.0.0.0:10080; steps 1 and 2 are then not needed, but the firewall rule is.
Leave a Comment