We recently moved a web application into Windows Azure that was using session state. As it was running on a single webserver the session state was set to InProc but this is not useful when in a multi-server environment as the session is stored on the specific machine and is therefore not accessible to other machines. There were a number of options:
- Use the Windows AppFabric Caching service (http://msdn.microsoft.com/en-us/library/windowsazure/gg278339.aspx)
- Use SQL Azure (http://blogs.msdn.com/b/sqlazure/archive/2010/08/04/10046103.aspx)
- Use Windows Azure Storage
Windows Azure Storage seemed to be the more cost effective version as the site does not currently use SQL Azure and they have purchased a subscription for Azure which includes both transaction and storage costs.
There is a sample asp.net session provider that uses Windows Azure Table Storage as its backing store. The sample can be downloaded from MSDN at
How to use the Azure Storage Session State Provider
Add the following Session State provider config to the web.config file of the project
1: <!-- SessionState Provider Configuration -->
2: <sessionState mode="Custom"
6: <add name="TableStorageSessionStateProvider" type="Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider"/>
Add your windows azure storage connection string (DataConnectionString) to each web role that requires session state (Not setting this will result in an object reference not set to an instance of an object exception)
Add a reference to the ASPProviders.dll taken from the sample project and make sure that the Copy Local property is set to true (Not setting this will cause an unable to load exception)
We also added a reference to System.DataServices.Client and set copy local to true on this too.(Not sure if this is needed)
Once this is setup and running, add multiple instances to your role configuration and run in the debugger. Make sure you can navigate to the page that has the session data in. I put a break point onto the action of the page and added a watch for Microsoft.WindowsAzure.ServiceRuntime.RoleInstance.CurrentRoleInstance.Id and checked to see if it changed and if it did change checked to see if the session data was visible.
You may well get the following error when you are using session as all the objects that are put into the Azure Table Storage session object need to be serializable.
Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode.
You can check to see the session data in the Azure Storage Server Explorer.
We are going to run this for a while to se how well it works and also see what debris is left behind in the table and blob storage due to ended sessions. We might have to have a job running that tidies up the expired sessions later.
This week we had a very useful side effect of using the Window Azure Service bus. We have an Azure hosted website that connects to a CRM backend using the service bus in relay mode to communicate between the two systems. We had a test system that worked fine but when we moved to a Live system we had a configuration error in one of the systems but it was difficult to identify.
The way the service bus works means that the server can easily be moved (as long as the server has an outgoing internet connection).Our service bus at the server side is a Windows Service but we also have a console application to help us with debugging as all the traces are logged to the console window. We turned off the service on the Live system and started it on the test system. As the Azure hosted website is connecting to the service bus rather than a specific server the website will now connect to our test system. By running a successful connection test on the Azure hosted site we could prove that the Azure website configuration was correct.
The next change was to configure the test system to point to the Live CRM system. This would prove whether our data was correct or not. Running the same test as before proved that our data migration to the Live CRM system was fine.
This left us with the service bus and the business logic web service running on the test system, so we reconfigured the Live service bus service to point to the Test web service (which we had previously configured to connect to the live CRM system) and this also work. Thus proving we had an issue with the business logic service.
What we were able to do then was to move the service bus console application on to a developers machine and run it in Visual Studio so that we could debug and break on the calls to the business logic service which helped us to easily identify the problem. All this was done without needing to reconfigure or redeploy our Azure hosted website.
I wish I could say that this ease of debugging was one of the reasons we chose to use the service bus, but I would be lying. The fact that it has made our debugging so much easier will now have an influence on its future use.
A new release of the Windows Azure Tools for Visual Studio 2010 is available here
The release adds the following features:
- Profile applications running in Windows Azure.
- Create ASP.Net MVC3 Web Roles.
- Manage multiple service configurations in one cloud project.
- Improved validation of Windows Azure packages.
The Windows Azure Platform Training Kit has also be updated in line with this release. It can be downloaded from here. The training kit has the following changes:
- [Updated] Labs and Demos to leverage the August 2011 release of the Windows Azure Tools for Microsoft Visual Studio 2010
- [Updated] Windows Azure Deployment to use the latest version of the Azure Management Cmdlets
- [Updated] Exploring Windows Azure Storage to support deleting snapshots
- Applied several minor fixes in content
When trying to access the Azure Storage SDK in a non-Azure application I kept getting the following error:
“The type or namespace name 'WindowsAzure' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) “
References to Microsoft.WindowsAzure.ServiceRuntime and Microsoft.WindowsAzure.StorageClient were both already included as references to the assembly that was trying to store data in a table. After a bit of investigation the reason for the error was that the assembly was set to have the target framework of “.Net Framework 4 Client Profile”. Changing to “.Net Framework 4” solved the problem.
For those trying to workout how much an Azure deployment will cost there is a new tool provided by Microsoft to help. The tool nicely swaps between currencies and also show the offers that are available.
Recently I was helping out at the Azure Bootcamp in London and during the labs a common theme kept occurring when the labs were deployed to a real Azure account. The roles failed to run and it appeared that the deployment was taking forever. This is something I experienced first hand when I was starting out with Azure. There is a way to diagnosing these deployment errors and it is by using IntelliTrace. During deployment you can enable IntelliTrace as part of the publish dialog
The IntelliTrace option is only available if you have Visual Studio 2010 Ultimate. Once deployed to Azure the Roles will attempt to start and any errors during this phase will lead to the symptoms mentioned above. You can then connect to your Azure environment using the Server Explorer in Visual Studio to retrieve the IntelliTrace files which can be opened in Visual Studio and show any exceptions that may have been thrown. Further information can be found here. Once you have diagnosed your issue please ensure at you then disable the IntelliTrace by redeploying the fixed application as it will have a negative impact on performance if left enabled.
Getting back to the problem we have at the Bootcamp, the issues was that the deployed application was trying to writing information to Azure storage and the connection string was still pointing to Development storage. This was strange because none of the deployed applications had got to the Azure storage part of the lab so you would have thought that there was no need for a connection string. Luckily I had the exact same problem with one of my earlier deployments and it turns out that when a project is created the Diagnostic plug-in is automatically enabled. The diagnostic plug-in requires its own connection string to Azure storage so that the diagnostic information can be stored. Looking at the role configuration in Visual Studio you can see the Diagnostic plug-in configuration.
To fix the deployment issue click the button next to the connection string text box and enter the details of your Azure Storage account.
You will need to redeploy the application or upload the new ServiceConfiguration.cscfg to fix this issue. If this still does not resolve the issue then try disabling the Diagnostics plug-in and redeploy.
Microsoft have announced two new Azure AppFabric CTPs.
May 2011 CTP will include Service bus enhancements including
- A more comprehensive pub/sub messaging
- Integration with the Access Control Service V2
- Queues based upon a new messaging infrastructure backed by a replicated, durable store.
See here for more details.
June 2011 CTP will include tooling to help with building, deploying and managing Windows Azure Applications including:
- AppFabric Developer Tools
- AppFabric Application Manager
- Composition Model
See here for more details
The SQL May 2011 update contains the following:
- SQL Azure Management REST API – a web API for managing SQL Azure servers.
- Multiple servers per subscription – create multiple SQL Azure servers per subscription.
- JDBC Driver – updated database driver for Java applications to access SQL Server and SQL Azure.
- DAC Framework 1.1 – making it easier to deploy databases and in-place upgrades on SQL Azure.
See here for more details
When deploying an Access Control Service enabled web application from my development environment to Windows Azure I got the following error:
“Unable to find assembly ‘Microsoft.IdentityModel, Version=18.104.22.168. . .”
This had worked well when running in the development fabric on my machine so it was strange that it failed when deployed to Windows Azure. The reason why this file cannot be found is because on my machine it is installed in the GAC and it is not in the GAC when deployed in Azure. There is a simple way to fix this and it is by configuring a Start-up task in your ServiceDefinition.csdef file to install the Microsoft.IdentityModel assembly in the GAC. When a new instance is created within Windows Azure the start up task will be run to allow things to be installed into the virtual machine prior to running your application.
Steve Marx has written an introduction to Start-up tasks as well as a Tips, Tricks and Gotchas list.
This post explains how to create a Start-up task to add an assembly to the GAC.
I’ve been developing a web application that adds rules to the access control service when a user registers with my website. This was working well using the ACS in AppFabricLabs. When I ported across to ACS V2 in the live environment I kept getting an exception thrown whenever I tried to retrieve information via the management service api.
The exception details are
The remote server returned an error: (400) Bad Request.
Status = protocol error
After investigation by looking at the latest ACS code samples on MSDN I noticed that the protocol has actually changed in the Common assembly ManagementServiceHelper.cs class. Comparing the code and copying the changes across to mine fixed the problems.
I also noticed that today that AppfabricLabs was updated last night and now uses the same protocol as V2 Live so you will need to make these changes anyway.
The Windows Azure SDK 1.4 refresh is available which adds in Web Deploy integration. This allows the developers to increase their productivity by using web deploy rather than having to repackage and redeploy the application. It is available for down load here and click the “Get Tools & SDK” button. Further information on this release can be found here