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 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>
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).
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
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?
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
Are you using FireFox?
Do you have PUT configured for extension-less URLs?
Do you mean PUT configured as in the first step mentioned above?
ExtensionlessUrl-Integrated-4.0?
Yes. I added it to the web.config.
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