As ASP.NET 5 hit RC1 about a month go, more and more folks are looking at production deployments and other real life use cases of it. Going beyond demoware and experiments, to real applications, inevitably leads to thinking about hosting it somewhere – which, if your environment is Windows, most likely means IIS.

I have recently gone through quite some trouble getting it all to work, so I thought it might be useful to document and highlight some of the steps, which hopefully will save a bit of your time.

Adjusting your application

In order to be able to run on IIS, your application needs to include Microsoft.AspNet.IISPlatformHandler package. There is currently an 1.0.0-rc1-final version available which should be added as a dependency to your project.json.

You should then add the platform handler middleware to the Configure method in your Startup class:

app.UseIISPlatformHandler(); 1 app . UseIISPlatformHandler ( ) ;

If you are using the latest (RC1) ASP.NET 5 templates, then the ASP.NET 5 Web Application template already references the Microsoft.AspNet.IISPlatformHandler package and even has the above line of code in the Startup class by default.

Publishing your application

First of all you need to publish your application. If you are really old school, you may want to do it from Visual Studio and its classic “Publish” dialog, but it will not do anything magical – all it will do is just call into the command line dnu tool.

So instead, you can call it yourself from the folder of your web application (you can also pass the path to the web application project if you wanna invoke dnu from anywhere) and save yourself a hassle of even opening Visual Studio (or maybe you are on a Unix and you don’t even have it).

dnu publish --runtime active 1 dnu publish -- runtime active

This command will publish your project and include the currently active runtime. You can obviously include a specific runtime too if that’s your intention, by passign its name. The publish command has plenty of other options such as for example specifying the source inclusion or the out path.

λ dnu publish --help Usage: dnu publish [arguments] [options] Arguments: [project] Path to project, default is current directory Options: -o|--out <PATH> Where does it go --configuration <CONFIGURATION> The configuration to use for deployment (Debug|Release|{Custom}) --no-source Compiles the source files into NuGet packages --framework Name of the frameworks to include. --iis-command Overrides the command name to use in the web.config for the httpPlatformHandler. The default is web. --runtime <RUNTIME> Name or full path of the runtime folder to include, or "active" for current runtime on PATH --native Build and include native images. User must provide targeted CoreCLR runtime versions along with this option. --include-symbols Include symbols in output bundle --wwwroot <NAME> Name of public folder in the project directory --wwwroot-out <NAME> Name of public folder in the output, can be used only when the '--wwwroot' option or 'webroot' in project.json is specified --quiet Do not show output such as source/destination of published files -?|-h|--help Show help information 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 λ dnu publish -- help Usage : dnu publish [ arguments ] [ options ] Arguments : [ project ] Path to project , default is current directory Options : - o | -- out < PATH > Where does it go -- configuration < CONFIGURATION > The configuration to use for deployment ( Debug | Release | { Custom } ) -- no - source Compiles the source files into NuGet packages -- framework Name of the frameworks to include . -- iis - command Overrides the command name to use in the web .config for the httpPlatformHandler . The default is web . -- runtime < RUNTIME > Name or full path of the runtime folder to include , or "active" for current runtime on PATH -- native Build and include native images . User must provide targeted CoreCLR runtime versions along with this option . -- include - symbols Include symbols in output bundle -- wwwroot < NAME > Name of public folder in the project directory -- wwwroot - out < NAME > Name of public folder in the output , can be used only when the '--wwwroot' option or 'webroot' in project .json is specified -- quiet Do not show output such as source / destination of published files - ? | - h | -- help Show help information

By default, the output path is bin/output in the same folder as your web application. The output can be xcopied to the server just like that.

The published source should have the following structure:

Inside the approot folder there will be a web.cmd file which can be used to start your app. You can also start it by simply getting into wwwroot and calling dnx web. Of course IIS knows nothing about all this, so you’ll need some extra IIS setup to make it understand the external DNX process.

Setting up IIS

The prerequisite in IIS is that the HttpPlatformHandler module needs to be installed (minimum version 1.2). This component is nothing ASP.NET 5 specific – it simply allows process management for external processes that listen for HTTP requests and proxies requests into it; in this case it will be dnx.exe but it might as well be something like node.exe. You can install the latest handler using direct installer or WebPI from IIS download site here.

Once you have published your ASP.NET 5 app (previous step), you can proceed to setting up IIS.

Create a new application, and set the .NET CLR version on application pool to No managed code. We’ll be calling into dnx.exe to start your application, rather relying on the classic w3wp process.

Point your website to the wwwroot folder inside your publish output (previous step) location – or wherever you copied it to. If you run the application pool using the application pool identity, you have to make sure that IIS_IUSRS has access to your publish folder.

If you navigate to your site now and everything just works, then great – you can stop reading this post as your job is done, but at this point, chances are things will not be working yet.

That wwwroot has a web.config file inside which should at this point look like this:

<configuration> <system.webServer> <handlers> <add name="httpplatformhandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" /> </handlers> <httpPlatform processPath="..\approot\web.cmd" arguments="" stdoutLogEnabled="false" stdoutLogFile="..\logs\stdout.log" startupTimeLimit="3600"></httpPlatform> </system.webServer> </configuration> 1 2 3 4 5 6 7 8 <configuration> <system.webServer> <handlers> <add name = "httpplatformhandler" path = "*" verb = "*" modules = "httpPlatformHandler" resourceType = "Unspecified" /> </handlers> <httpPlatform processPath = "..\approot\web.cmd" arguments = "" stdoutLogEnabled = "false" stdoutLogFile = "..\logs\stdout.log" startupTimeLimit = "3600" > </httpPlatform> </system.webServer> </configuration>

You may want to set that stdoutLogEnabled=“false” to true immediately cause you’d want to get the errors, normally written to stdout of a hidden process, to be redirected to the log file.

Resolving errors

One possibility is that you see the following HTTP Error 500.19:

This is because at the global config level, the system.webServer/handlers section is locked. To unlock it, go to IIS Manager, select your server root in the left navigation tree, then choose “Configuration Editor” > type system.webServer/handlers in the section selection dropdown and press enter. Then choose “unlock section” from the right action pane.

Another (or next) potential issue that you may encounter, is that you see a blank page, that appears to be stuck loading forever. If that’s the case check the logs folder under the path defined in the web.config.

Most likely possibility is that dnx command is not being recognized. The reason for this is that the user used to run the IIS process doesn’t have it in the PATH. To combat this, you can do a few things:

change the application pool user to a one that has DNX on the PATH (i.e. your own user account)

add the DNX environment variables as a system-wide variables: DNX_HOME, should point to your DNX folder, for me it’s C:\Users\filip\.dnx DNX_PACKAGES, should point to your DNX packages folder, for me it’s C:\Users\filip\.dnx\packages DNX_PATH, should point to your DNVM cmd file, for me it’s C:\Users\filip\.dnx\bin\dnvm.cmd If you choose this approach, you have to make sure that IIS_IUSRS has access to all the above folders too. Note that on IIS 10 you can also set environment variables specifically for the application pool.

instead of using …\approot\web.cmd to start up your application, you can also hardcode a path to dnx in the processPath attribute of the httpPlatform inside web.config. If you do that, you also need to pass the web argument in the arguments attribute

Finally, there might some other issues not mentioned here, that you can identify through the log file. For example, perhaps you provided a custom path to the dnx.exe but have not provided the arguments (“web”). This type of error would simply show up in the log as the usage help for dnx.

Overall, I tried this process on IIS 7.5, IIS 8 and IIS 10 – and at the end it ran successfully everywhere