Azure Full IIS: RoleEntryPoint runs in different process to web app

I just found this one out thanks to this post from the Azure team.

Basically, I was configuring Table Storage (as you may have guessed, if you’ve read my other posts today), and using the CloudStorageAccount.FromConfigurationSetting(string) method. As you are probably aware (if you are aware of this sort of stuff), to be able to use that method, you must first set a function that tells Cloud Storage how to figure out how to get configuration settings. You do that with the CloudStorageAccount.SetConfigurationSettingPublisher(Action> configurationSettingPublisher) method. I knew that.

So I put it in my WebRole class, which inherits from RoleEntryPoint. That was fine. Code within my WebRole.OnStart method that used Table Storage was fine.

But when some of my other code, inside the web app, tried to access Table Storage, I got the exception saying I hadn’t called SetConfigurationSettingPublisher. It turns out that with Full IIS in Azure (which is the default if you create a project using the SDK version 1.3), the RoleEntryPoint runs in a different process (WaIISHost.exe, apparently) and my app runs under w3wp.exe.

And this exact problem is mentioned in that blog article, under the heading “Accessing Static Members from RoleEntryPoint and your web site”.

As annoying as this is, I’m kind of glad I figured out the problem (it all comes down to search keywords) in such a short amount of time!

Microsoft.WindowsAzure.StorageClient is not actually on Azure

And neither is Microsoft.WindowsAzure.Diagnostics.

It’s ironic that the diagnosis of Windows Azure roles failing to start up is that the Diagnostics assembly isn’t present.

I’ve spent the better part of a day trying to figure out why things weren’t working. According to countless forum posts, blog articles and MSDN articles, the main reason that roles fail to fire up and end up cycling between initializing and busy is that there are dependent files missing. I assumed (wrongly) that the Microsoft.WindowsAzure.* assemblies would be present because… well… it’s Microsoft Windows Azure. I was wrong.

It kind of makes sense, because you might not want to use all features of Azure. But you have to forgive me for assuming they’d be there.

I figured it out by running Intellitrace on the instance. I could download the Intellitrace log and I could see that there was a nice big System.IO.FileNotFoundException. It couldn’t load Microsoft.Windows.StorageClient. I did a bit more research and eventually found out that you need to Copy Local that assembly, and Diagnostics, too.

A post from Think First, Code Later, was the final bit of info that made everything else make sense!

This has been a big weekend for blog posts for me, hasn’t it?

Running ASP.NET MVC 3 on Azure

If you have successfully installed an app running MVC 2 on Azure, and then try to upgrade it to MVC 3, you might run into some troubles.

What might help is to ensure that you have also deployed the new assemblies. MVC 2 is part of .NET 4.0, and its assemblies are included in the standard Azure image, but the new ones aren’t. You have to deploy them yourself.

They won’t get deployed by default because they are in the GAC. You have to make sure that “Copy Local” is selected for the relevant MVC assemblies.

The instructions on how to upgrade and MVC 2 project to MVC 3 are in the release notes, and involve replacing some of the old references with the new ones. But those assemblies have dependencies that aren’t copied.

The assemblies I needed to run an MVC 3 project (using Razor) on Azure are:

  • Microsoft.Web.Infrastructure
  • System.Web.Mvc
  • System.Web.Razor
  • System.Web.WebPages
  • System.Web.WebPages.Deployment
  • System.Web.WebPages.Razor

I’m not 100% I needed System.Web.WebPages.Razor, but it seemed like a good one to have.

I did not need System.Web.WebPages.Administration. If you include that, you need to include NuGet as well.

I don’t actually know what any of those assemblies specifically do (I don’t know what the WebPages or Microsoft.Web.Infrastructure assemblies are for), but this is what I’ve needed to deploy to get it to work.

Azure 1.3, Rewrite module and a ‘Faulted’ System.ServiceModel.Channels.ServiceChannel

I recently updated to Azure SDK 1.3. Then I tried to debug my solution locally. This is where the trouble began. The problem was that I was using the IIS Rewrite module without having it installed. Rewrite was part of Azure SDK 1.2, but it has to be installed separately for 1.3. I guess I should have read the release notes.

Here is what the problem was, and how I found the solution.

I would consistently get the following exception:

System.ServiceModel.CommunicationObjectFaultedException was unhandled
Message=The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
Source=mscorlib
StackTrace:
Server stack trace:
at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at System.ServiceModel.ICommunicationObject.Close(TimeSpan timeout)
at System.ServiceModel.ClientBase`1.System.ServiceModel.ICommunicationObject.Close(TimeSpan timeout)
at Microsoft.WindowsAzure.Hosts.WaIISHost.Program.Main(String[] args)
InnerException:

It didn’t make any sense.

Most of the support out there (like here) suggested that it was because I was using a using (...) { } block around a ServiceClient. Something about exceptions that get raised during the ServiceClient‘s Close method being swallowed up into that generic one. But it wasn’t that. My code didn’t consume any WCF services.

I thought it might have been the Facebook SDK. It couldn’t have been log4net or Netwonsoft.JSON, either.

Another suggestion was that WebRole’s Web.config file was not writeable. That wasn’t the case either.

It turns out it was the use of the section in Web.config. What also didn’t help was that I had two sections by mistake as well (the result of a bad merge). According to the Windows Azure SDK Release Notes, “If you wish to use the IIS URL Rewrite module, you must install it and configure your rewrite rules.”

Once I installed that, I was able to run my solution with the Rewrite rules intact.

I suspected that the problem wasn’t really that the IIS Rewrite module hadn’t been installed, but that the unrecognised Web.config section caused it to fall down. That suspicion was confirmed when I added a element to my Web.config. The exact same CommunicationObjectFaultedException was raised.

So the golden rule is to your Web.config if you get a CommunicationObjectFaultedException when running an Azure solution locally.

Windows Azure Development Storage with real SQL Server

I don’t have SQL Server Express, I’ve got the real deal. Development Storage for Windows Azure assumes you are using SQL Server Express with the instance name SQLEXPRESS.

Thanks to this article I now know that you just need to edit the config file for DevelopmentStorage.exe, which is usually located in C:Program FilesWindows Azure SDKv1.0binDevelopmentStorage.exe.config.

There are two spots to modify. The first is the connection string (XPath: /configuration/connectionStrings/add/@connectionString) and the second is the dbServer attribute of the Table service (XPath: /configuration/developmentStorgeConfig/service/service[@name='Table']/@dbServer).

And then it will work. Enjoy!