Configuration Tips For ASP.NET MVC 4 on a Windows Azure Website

Tuesday, August 7, 2012

The new Windows Azure Website feature is easy to use. You can deploy an application by publishing from  Visual Studio or by pushing code with git. There are a few extra configuration steps I’ve found useful.

Using HTTP PUT and DELETE with the ASP.NET WebAPI

Using PUT and DELETE with Azure (or IIS, or IIS Express for that matter) requires some extra configuration before the server will allow messages with these methods into the processing pipeline. By default, IIS will only allow GET, HEAD, POST, and DEBUG. The following configuration section goes inside of <system.webserver>, and will tell IIS to process PUT and DELETE, too.

Note: the final release version of ASP.NET MVC 4 will include this configuration in web.config by default when you create a new project*, but it is still handy for upgrades and to generally know why it exists.

<handlers>
<remove name="ExtensionlessUrl-Integrated-4.0" />
<add name="ExtensionlessUrl-Integrated-4.0"
path="*."
verb="GET,HEAD,POST,DEBUG,DELETE,PUT"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

The Usual HTML 5 Media Types

Before IIS will serve a static file it needs to know the media type associated with the file. Video and SVG files were refusing to work until I added the following (also in the <system.webserver> section of web.config):

<staticContent>
<remove fileExtension=".mp4"/>
<remove fileExtension=".ogv"/>
<remove fileExtension=".webm"/>
<remove fileExtension=".svg"/>
<mimeMap fileExtension=".mp4" mimeType="video/mp4" />
<mimeMap fileExtension=".ogv" mimeType="video/ogg" />
<mimeMap fileExtension=".webm" mimeType="video/webm" />
<mimeMap fileExtension=".svg" mimeType="image/svg+xml"/>
</staticContent>

The <remove> entries will allow the configuration to work even on local servers that already have the media types configured (you’ll have a runtime error if you add a duplicate entry, but there is no error if you remove an entry that doesn’t exist).

Automatic Migrations

Finally, if you are using Code First Entity Framework migrations you can have them execute automatically after a release push by adding  to the Web.Release.config file. Web.config transformations even work with git deployments to Azure.

<entityFramework>
<contexts xdt:Transform="Insert">
<context type="EmployeeApp.EmployeeDb, MvcApplication10">
<databaseInitializer
type="System.Data.Entity.MigrateDatabaseToLatestVersion`2[
[EmployeeApp.EmployeeDb,MvcApplication10],
[MvcApplication10.Migrations.Configuration, MvcApplication10]
], EntityFramework"
/>
</context>
</contexts>
</entityFramework>

Of course you’ll need to substitute your own DbContext and Configuration types as the generic type parameters to MigrateDatabaseToLatestVersion. See EF 4.3 Configuration File Settings for more details (yes, it works with EF 5.0, too).

* MVC 4 will also configure ExtensionlessUrlHandler-ISAPI-4.0_32bit and ExtensionlessUrlHandler-ISAPI-4.0_64bit.


Comments
Jarmo Jokela Wednesday, August 8, 2012
Thank you! Very useful tips.
Don Wednesday, August 8, 2012
Thanks for the tips, useful. Appreciate the reference links too.
gravatar PeteK68 Wednesday, August 8, 2012
Hi Scott, thanks for the tips.

I have a library which I use:
lib.update(path, data, successCallback, failCallback);

The implementation of update(...) is:
$.ajax({
type: "PUT",
url: url,
data: data
}).success(successCallback)
.error(errorCallback);

This call seems to trigger an OPTIONS request to the server (I'm guessing to see if PUT is an accepted verb). The response from IIS is:
HTTP/1.1 200 OK
Allow: OPTIONS, TRACE, GET, HEAD, POST
Server: Microsoft-IIS/8.0
Public: OPTIONS, TRACE, GET, HEAD, POST
X-SourceFiles: =?UTF-8?B?[TRUNCATED]
X-Powered-By: ASP.NET
Date: Wed, 08 Aug 2012 21:33:38 GMT
Content-Length: 0

And it shows up in red in Chrome, because PUT is not returned as valid.

Any ideas why this is happening?
gravatar PeteK68 Wednesday, August 8, 2012
Here is the request:

OPTIONS /api/Users HTTP/1.1
Host: localhost:11980
Connection: keep-alive
Cache-Control: max-age=0
Access-Control-Request-Method: PUT
Origin: http://localhost:1380
Pragma: no-cache
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.60 Safari/537.1
Access-Control-Request-Headers: origin, content-type, accept
Accept: */*
Referer: http://localhost:1380/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-CA,en-US;q=0.8,en;q=0.6,fr-CA;q=0.4
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
gravatar Scott Allen Wednesday, August 8, 2012
@Pete:

Are you using FireFox?

Do you have PUT configured for extension-less URLs?
gravatar PeteK68 Wednesday, August 8, 2012
@Scott, no I'm using Chrome.

Do you mean PUT configured as in the first step mentioned above?

ExtensionlessUrl-Integrated-4.0?

Yes. I added it to the web.config.
gravatar scott Thursday, August 9, 2012
Thinking it must be going to a different handler - any chance you can turn on request tracing a grab the log file?
gravatar PeteK68 Thursday, August 9, 2012
Hey Scott. I turned on request tracing. How do you want me to send you the file?

I think it has to do with the fact that I have my Web API running in a separate project from my MVC that consumes it. This makes the ports different, and I think it makes jquery think it's across domains. Maybe?

P
gravatar Domlia Friday, August 10, 2012
Good tips, especially automatic migrations. Thanks.
gravatar Scott Allen Saturday, August 11, 2012
@PeteK - ah, yes, that would look like a cross domain request to the browser. You might want to look at the sample code associated with this project: blogs.msdn.com/...
gravatar Eric Greene Friday, August 17, 2012
I got my MVC 4 app running on Azure Websites... Very cool... But when I make changes to the cshtml files the changes never appear when viewing the web page. I have deleted all files and republished, I have use my FTP program to open a file, edit it and save it and no changes appear. When I edit a stylesheet is updates as expect just not the cshtml content. Any ideas?
gravatar scott Friday, August 17, 2012
@Eric - that seems odd. Is this an MVC app? Are you using OutputCache attributes?
Comments are now closed.
by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!