[iis] Using Custom Domains With IIS Express

Traditionally I use custom domains with my localhost development server. Something along the lines of:

dev.example.com
dev.api.example.com

This has provided me a ton of flexibility when working with external API's such as Facebook. This has worked great in the past with the built in Visual Studio Development Server, because all I needed to do was add a CNAME to those DNS records pointing to 127.0.0.1.

However I have not been able to get this to work with IIS Express. Everything I have tried seems to have failed. I have even added the correct XML config to the applicationHost.config file for IIS Express, but it doesn't seem to recognize the entries as valid as a true install of IIS would.

<binding protocol="http" bindingInformation="*:1288:dev.example.com" />

Whenever I enter this line and try to request http://dev.example.com:1288 I get the following message:

Bad Request - Invalid Hostname

Does anybody know if I am missing something obvious? Or did the IIS Express team really lack the foresight to see this type of use?

This question is related to iis iis-7 iis-express

The answer is


Leaving this here just in case anyone needs...

I needed to have custom domains for a Wordpress Multisite setup in IIS Express but nothing worked until I ran Webmatrix/Visual Studio as an Administrator. Then I was able to bind subdomains to the same application.

<bindings> 
    <binding protocol="http" bindingInformation="*:12345:localhost" />
    <binding protocol="http" bindingInformation="*:12345:whatever.localhost" />
</bindings>

Then going to http://whatever.localhost:12345/ will run.


When using Visual Studio 2012 with IIS Express, changing an existing binding does not work permanently. (It may work until you close VS, but after that, things get really messed up.)

The key is keeping the existing localhost binding and adding a new binding after it.

Unless you're running as administrator, you'll also need to run netsh add urlacl (to give yourself permissions to run a non-localhost site as a standard user).

If you want to allow any host name, the full process is as follows:

  1. Create your web application, and find out what port it is using (see project properties, Web tab, Project Url).
  2. From an administrator prompt, run the following commands (replacing portnumber with the port number you figured out in #1):

    netsh http add urlacl url="http://*:portnumber/" user=everyone
    netsh http add urlacl url="http://localhost:portnumber/" user=everyone
    

You can also use your user name (DOMAIN\USER) instead of everyone for better security.

  1. Open applicationhost.config (usually under My Documents\IIS Express\config), and find the element with your port number.
  2. Add one more binding with the host name you want (in this case, *). For example:

    <site name="MvcApplication1" id="2">
        <application path="/" applicationPool="Clr4IntegratedAppPool">
            <virtualDirectory path="/" physicalPath="C:\sites\MvcApplication1" />
        </application>
        <bindings>
            <binding protocol="http" bindingInformation="*:12853:localhost" />
            <binding protocol="http" bindingInformation="*:12853:*" />
        </bindings>
    </site>
    

Note that, if want to open up all host names (*), you'll need two netsh commands (one for * and one for localhost). If you only want to open up a specific host name, you don't strictly need the second netsh command (localhost); just the one with your specific host name is sufficient.


I was trying to integrate the public IP Address into my workflow and these answers didn't help (I like to use the IDE as the IDE). But the above lead me to the solution (after about 2 hours of beating my head against a wall to get this to integrate with Visual Studio 2012 / Windows 8) here's what ended up working for me.

applicationhost.config generated by VisualStudio under C:\Users\usr\Documents\IISExpress\config

    <site name="MySite" id="1">
        <application path="/" applicationPool="Clr4IntegratedAppPool">
            <virtualDirectory path="/" physicalPath="C:\Users\usr\Documents\Visual Studio 2012\Projects\MySite" />
        </application>
        <bindings>
            <binding protocol="http" bindingInformation="*:8081:localhost" />
            <binding protocol="http" bindingInformation="*:8082:localhost" />
            <binding protocol="http" bindingInformation="*:8083:192.168.2.102" />
        </bindings>
    </site>
  • Set IISExpress to run as Administrator so that it can bind to outside addresses (not local host)
  • Run Visual Stuio as an Administrator so that it can start the process as an administrator allowing the binding to take place.

The net result is you can browse to 192.168.2.102 in my case and test (for instance in an Android emulator. I really hope this helps someone else as this was definitely an irritating process for me.

Apparently it is a security feature which I'd love to see disabled.


For Visual Studio 2015 the steps in the above answers apply but the applicationhost.config file is in a new location. In your "solution" folder follow the path, this is confusing if you upgraded and would have TWO versions of applicationhost.config on your machine.

\.vs\config

Within that folder you will see your applicationhost.config file

Alternatively you could just search your solution folder for the .config file and find it that way.

I personally used the following configuration:

enter image description here

With the following in my hosts file:

127.0.0.1       jam.net
127.0.0.1       www.jam.net

And the following in my applicationhost.config file:

<site name="JBN.Site" id="2">
    <application path="/" applicationPool="Clr4IntegratedAppPool">
        <virtualDirectory path="/" physicalPath="C:\Dev\Jam\shoppingcart\src\Web\JBN.Site" />
    </application>
    <bindings>
        <binding protocol="http" bindingInformation="*:49707:" />
            <binding protocol="http" bindingInformation="*:49707:localhost" /> 
    </bindings>
</site>

Remember to run your instance of visual studio 2015 as an administrator! If you don't want to do this every time I recomend this:

How to Run Visual Studio as Administrator by default

I hope this helps somebody, I had issues when trying to upgrade to visual studio 2015 and realized that none of my configurations were being carried over.


I was using iisexpress-proxy (from npm) for this.

https://github.com/icflorescu/iisexpress-proxy


On my WebMatrix IIS Express install changing from "*:80:localhost" to "*:80:custom.hostname" didn't work ("Bad Hostname", even with proper etc\hosts mappings), but "*:80:" did work--and with none of the additional steps required by the other answers here. Note that "*:80:*" won't do it; leave off the second asterisk.


David's solution is good. But I found the <script>alert(document.domain);</script> in the page still alerts "localhost" because the Project Url is still localhost even if it has been override with http://dev.example.com. Another issue I run into is that it alerts me the port 80 has already been in use even if I have disabled the Skype using the 80 port number as recommended by David Murdoch. So I have figured out another solution that is much easier:

  1. Run Notepad as administrator, and open the C:\Windows\System32\drivers\etc\hosts, add 127.0.0.1 mydomain, and save the file;
  2. Open the web project with Visual Studio 2013 (Note: must also run as administrator), right-click the project -> Properties -> Web, (lets suppose the Project Url under the "IIS Express" option is http://localhost:33333/), then change it from http://localhost:33333/ to http://mydomain:333333/ Note: After this change, you should neither click the "Create Virtual Directory" button on the right of the Project Url box nor click the Save button of the Visual Studio as they won't be succeeded. You can save your settings after next step 3.
  3. Open %USERPROFILE%\My Documents\IISExpress\config\applicationhost.config, search for "33333:localhost", then update it to "33333:mydomain" and save the file.
  4. Save your setting as mentioned in step 2.
  5. Right click a web page in your visual studio, and click "View in Browser". Now the page will be opened under http://mydomain:333333/, and <script>alert(document.domain);</script> in the page will alert "mydomain".

Note: The port number listed above is assumed to be 33333. You need to change it to the port number set by your visual studio.

Post edited: Today I tried with another domain name and got the following error: Unable to launch the IIS Express Web server. Failed to register URL... Access is denied. (0x80070005). I exit the IIS Express by right clicking the IIS Express icon at the right corner in the Windows task bar, and then re-start my visual studio as administrator, and the issue is gone.


Following Jaro's advice, I was able to get this working under Windows XP and IIS Express (installed via Web Matrix) with a small modification and was not limited to only localhost. It's just a matter of setting the bindings correctly.

  1. Use WebMatrix to create a new site from folder in your web application root.
  2. Close WebMatrix.
  3. Open %USERPROFILE%\My Documents\IISExpress\config\applicationhost.config (Windows XP. Vista and 7 paths will be similar) and edit the site definition in the <sites> config block to be along the lines of the following:

    <site name="DevExample" id="997005936">
        <application path="/" applicationPool="Clr2IntegratedAppPool">
            <virtualDirectory
                path="/"
                physicalPath="C:\path\to\application\root" />
        </application>
        <bindings>
            <binding
                protocol="http"
                bindingInformation="*:80:dev.example.com" />
        </bindings>
        <applicationDefaults applicationPool="Clr2IntegratedAppPool" />
    </site>

If running MVC, then keep the applicationPool set to one of the "Integrated" options.


The up-voted answer is valid.. and this information helped me quite a bit. I know this topic has been discussed before but I wanted to add some additional input. People are saying that you must "manually edit" the application.config file in the Users IISExpress/Config directory. This was a big issue for me because I wanted to distribute the configuration via Source control to various developers.

What I found is that you can automate the updating of this file using the "C:\Program Files\IIS Express\appcmd.exe" program. It took a while to find out the control parameters but Ill share my findings here. Essentially you can make a .bat file that runs both the NETSH command and the APPCMD.EXE (and perhaps swap out a host file if you like) to make host header configuration easy with IIS Express.

Your install bat file would look something like this:

netsh http add urlacl url=http://yourcustomdomain.com:80/ user=everyone 

"C:\Program Files\IIS Express\appcmd.exe" set site "MyApp.Web" /+bindings.[protocol='http',bindingInformation='*:80:yourcustomdomain.com']

I also will make a "Uninstall" bat file that will clean up these bindings..(because often times Im just faking out DNS so that I can work on code that is host name sensitive)

netsh http delete urlacl url=http://yourcustomdomain.com:80/

"C:\Program Files\IIS Express\appcmd.exe" set site "MyApp.Web" /-bindings.[protocol='http',bindingInformation='*:80:yourcustomdomain.com']

I hope this information is helpful to someone.. It took me a bit to uncover.


I tried all of above, nothing worked. What resolved the issue was adding IPv6 bindings in the hosts file. In step 5 of @David Murdochs answer, add two lines instead of one, i.e.:

127.0.0.1 dev.example.com
::1 dev.example.com

I figured it out by checking $ ping localhost from command line, which used to return:

Reply from 127.0.0.1: bytes=32 time<1ms TTL=128

Instead, it now returns:

Reply from ::1: time<1ms

I don't know why, but for some reason IIS Express started using IPv6 instead of IPv4.


Just in case if someone may need...

My requirement was:

  • SSL enabled
  • Custom domain
  • Running in (default) port: 443

Setup this URL in IISExpress: http://my.customdomain.com

To setup this I used following settings:

Project Url: http://localhost:57400

Start URL: http://my.customdomain.com

/.vs/{solution-name}/config/applicationhost.config settings:

<site ...>
    <application>
        ...
    </application>
    <bindings>
        <binding protocol="http" bindingInformation="*:57400:" />
        <binding protocol="https" bindingInformation="*:443:my.customdomain.com" />
    </bindings>
</site>

Like Jessa Flint above, I didn't want to manually edit .vs\config\applicationhost.config because I wanted the changes to persist in source control. I also didn't want to have a separate batch file. I'm using VS 2015.

Project Properties?Build Events?Pre-build event command line: Screenshot of project properties


::The following configures IIS Express to bind to any address at the specified port

::remove binding if it already exists
"%programfiles%\IIS Express\appcmd.exe" set site "MySolution.Web" /-bindings.[protocol='http',bindingInformation='*:1167:'] /apphostconfig:"$(SolutionDir).vs\config\applicationhost.config"

::add the binding
"%programfiles%\IIS Express\appcmd.exe" set site "MySolution.Web" /+bindings.[protocol='http',bindingInformation='*:1167:'] /apphostconfig:"$(SolutionDir).vs\config\applicationhost.config"

Just make sure you change the port number to your desired port.


This method has been tested and worked with ASP.NET Core 3.1 and Visual Studio 2019.

.vs\PROJECTNAME\config\applicationhost.config

Change "*:44320:localhost" to "*:44320:*".

<bindings>
    <binding protocol="http" bindingInformation="*:5737:localhost" />
    <binding protocol="https" bindingInformation="*:44320:*" />
</bindings>

Both links work:

Now if you want the app to work with the custom domain, just add the following line to the host file:

C:\Windows\System32\drivers\etc\hosts

127.0.0.1 customdomain

Now:

  • https://customdomain:44320

NOTE: If your app works without SSL, change the protocol="http" part.


The invalid hostname indicates that the actual site you configured in the IIS Express configuration file is (most likely) not running. IIS Express doesn't have a process model like IIS does.


For your site to run it would need to be started explicitly (either by opening and accessing from webmatrix, or from command line calling iisexpress.exe (from it's installation directory) with the /site parameter.


In general, the steps to allow fully qualified DNS names to be used for local access are Let's use your example of the DNS name dev.example.com

  1. edit %windows%\system32\drivers\etc\hosts file to map dev.example.com to 127.0.0.1 (admin privilege required). If you control DNS server (like in Nick's case) then the DNS entry is sufficient as this step is not needed.
  2. If you access internet through proxy, make sure the dev.example.com will not be forwared to proxy (you have to put in on the exception list in your browser (for IE it would be Tools/Internet Options/Connections/Lan Settings, then go to Proxy Server/Advanced and put dev.example.com on the exeption list.
  3. Configure IIS Express binding for your site (eg:Site1) to include dev.example.com. Administrative privilege will be needed to use the binding. Alternatively, a one-time URL reservation can be made with http.sys using

    netsh http add urlacl url=http://dev.example.com:<port>/ user=<user_name>

  4. start iisexpress /site:Site1 or open Site1 in WebMatrix


Examples related to iis

ASP.NET Core 1.0 on IIS error 502.5 CS1617: Invalid option ‘6’ for /langversion; must be ISO-1, ISO-2, 3, 4, 5 or Default Publish to IIS, setting Environment Variable IIS Manager in Windows 10 The page cannot be displayed because an internal server error has occurred on server The service cannot accept control messages at this time NuGet: 'X' already has a dependency defined for 'Y' Changing project port number in Visual Studio 2013 System.Data.SqlClient.SqlException: Login failed for user "This operation requires IIS integrated pipeline mode."

Examples related to iis-7

Accessing a local website from another computer inside the local network in IIS 7 500.21 Bad module "ManagedPipelineHandler" in its module list HTTP Error 503. The service is unavailable. App pool stops on accessing website IIS - 401.3 - Unauthorized 500.19 - Internal Server Error - The requested page cannot be accessed because the related configuration data for the page is invalid ASP.NET Web API application gives 404 when deployed at IIS 7 WebApi's {"message":"an error has occurred"} on IIS7, not in IIS Express enabling cross-origin resource sharing on IIS7 How to fix 'Microsoft Excel cannot open or save any more documents' IIS 7, HttpHandler and HTTP Error 500.21

Examples related to iis-express

HTTP Error 500.30 - ANCM In-Process Start Failure localhost refused to connect Error in visual studio How to solve ERR_CONNECTION_REFUSED when trying to connect to localhost running IISExpress - Error 502 (Cannot debug from Visual Studio)? Process with an ID #### is not running in visual studio professional 2013 update 3 Unable to launch the IIS Express Web server, Failed to register URL, Access is denied Why and how to fix? IIS Express "The specified port is in use" How can I change IIS Express port for a site Authentication issue when debugging in VS2013 - iis express ASP.NET MVC5/IIS Express unable to debug - Code Not Running How to solve “Microsoft Visual Studio (VS)” error “Unable to connect to the configured development Web server”