Wednesday 9 March 2011

Deploying an MVC .NET 4 application on IIS 7.5

I recently incorporated MVC 3 into an existing web application project.  In the process I upgraded the target framework to .NET 4.0.  I faced a number of issues on deploying the application to IIS 7.5.

The first problem was an Internal Server Error 500 HTTP response from the server.  The solution to this is to check the web.config file and remove the system.web/httpModules and system.web/httpHandlers sections.  For my application these were redundant and I was able to simply remove them.  If any modules and/or handlers are still needed by the application these should be moved to system.webServer/modules and system.webServer/handlers respectively.

The next error I faced was a Internal Server Error 500.21 mysteriously complaining that Handler PageHandlerFactory-Integrated has a bad module ManagedPipelineHandler in its module list.  It seems this was caused by ASP.NET 4 not being correctly registered with IIS 7.5.  The solution is to check that the version of .NET installed on the computer running IIS matches the version targeted by the application (on my computer this is v4.0.30319), and run the aspnet_regiis tool for the correct .NET version, e.g.:

%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe -i

You'll need to run this as an administrator.  You also need to check in IIS that the application pool used by the app is set to .NET 4.0 and Integrated managed pipeline.

If you're accessing a database and you haven't configured impersonation, you may need to set up a login for the ASP.NET identity. In ASP.NET 4 by default the application pool runs under the Windows account APPPOOL\[application pool name].  If you're using the default settings this will be APPPOOL\DefaultAppPool.  If you've upgraded to .NET 4, you'll have to create a login for each database your application accesses for the application pool Windows account.  (Alternatively if you have an existing login set up for the IIS 7 or 7.5 account you can change the application pool identity to this account.)

Having done these tasks I was able to run the application and log in, but as soon as I tried to access any MVC controller the server complained with a 404 response error.  After much googling I found this was fixed by applying hotfix KB980368.

This should now get you into the controller action.

One final error may crop up if you are restarting Cassini or IIS while testing the above, and this is related to any use of the Html.AntiForgeryToken method in views.  The default configuration is for a machine key to automatically generated: this will be invalidated each time IIS is restarted.  This is not a bug in the application: this is how it is supposed to work in production.  To clear this error you will need to clear out your application's cookies from your browser.  If you want to avoid this while testing - or in production if the ASP.NET process is being recycled (e.g. IIS restarts or if your application is being hosted in a web farm scenario) - you can hardwire a machine key by inserting a machine key section and either using a machine key generator tool to generate the machine key section e.g. aspnetresources.com/tools/machineKey or by manually creating a machine key section in system.web.