Windows Azure is an open cloud platform that enables you to quickly build, deploy and manage applications across a global network of Microsoft-managed datacenters. You can build applications using any language, tool or framework.
Windows Azure provides three options for executing applications. These options can be used separately or combined.
This tutorial demonstrates the process of creating a Windows Azure application and the process of deploying the application to a Windows Azure Cloud Service. The application is a simple golfer message board web application for users to enter or view messages, it contains one web role (Web front-end), that allows golfers to view the message board and add new message entries. The application uses the Windows Azure Table service to store messages. Here is a screenshot of the application:
Last reviewed: 11/04/2012
Note: The tutorial code has been tested on Windows Azure SDK (October 2012).
Note: For the tutorial in PHP, see Using the Windows Azure Web Role and Windows Azure Table Service with PHP.
In this tutorial, you will learn how to:
Note the following requirements before you begin this lesson:
The following diagram illustrates the development components and the runtime components involved in this tutorial:
Note: The gray out components are the components that are not covered in this tutorial but in other tutorials.
The Windows Azure Table service is structured storage in the cloud. Here is a diagram of the Table service data model:
An application must use a valid account to access Windows Azure Storage service. In lesson 5, you will create a new Windows Azure storage account using Windows Azure Management Portal. An application may create many tables within a storage account. A table contains a set of entities (rows). Each entity contains a set of properties. An entity can have at most 255 properties including the mandatory system properties - PartitionKey, RowKey, and Timestamp. "PartitionKey" and "RowKey" form the unique key for the entity.
In this lesson, you create a Windows Azure Project with Visual Studio. A Windows Azure application can contain one or more roles. The application you will develop in this tutorial only contains one web role talking to Windows Azure Table service. In [[Windows Azure and SQL Database Tutorials - Tutorial 4: Using Windows Azure Worker Role and Windows Azure Queue Service]], you will add a Worker role to the application for background processing.
In this lesson, you will go through the following procedure:
To create a Visual Studio project
Under the MessageBoard cloud service project, there are also one definition file and two configuration files. The ServiceDefinition.csdef file defines the runtime settings for the application including what roles are required, endpoints, and so on. The ServiceConfiguration.Local.cscfg contains the storage account connection string to use the local Windows Azure Storage emulator; the ServiceConfiguration.Cloud.cscfg file contains the settings to use Windows Azure storage service. For more information, see Configuring the Windows Azure Application with Visual Studio at http://msdn.microsoft.com/en-us/library/ee405486.aspx.
In this step, you created a Windows Azure project with Visual Studio.
You add a new class library project to the solution for accessing Windows Azure Table service.
Return to Top
The application stores message entries using Windows Azure Table service. The Table service is NOT relational database tables. It is helpful to think of it as object storage.
In this lesson, you first define the entity for golfer message entries. An entity contains a set of properties, for example, golfer name, and message. Then you create the data source so that the ASP.NET web role that you will create in the next lesson can use the data source to access the Table service. The data source has two methods, one for adding messages to the storage, and the other for listing the messages in the storage.
To access the Table service, you can use LINQ.
In this lesson, you will go through the following procedures:
To add a new project
Note: If multiple extension assemblies are presented, select the ones with version 1.7.0.0.
Note: If you cannot find a component, use the search box on the upper right corner of the dialog.
Next, define the entity for the message entries. The Table service does not enforce any schema for tables making it possible for two entities in the same table to have different sets of properties. Nevertheless, this message board application uses a fixed schema to store its data.
To define the entity
using Microsoft.WindowsAzure.StorageClient;
public class MessageBoardEntry : TableServiceEntity { }
public MessageBoardEntry() { PartitionKey = DateTime.UtcNow.ToString("MMddyyyy"); // Row key allows sorting, so we make sure the rows come back in time order. RowKey = string.Format("{0:10}_{1}", DateTime.MaxValue.Ticks - DateTime.Now.Ticks, Guid.NewGuid()); } public string GolferName { get; set; } public string GolferMessage { get; set; }
Note: You can either copy/paste the code or use code snippet. The code snippets have more comments which can help you to review the code in the future. For more information on using the code snippets, see [[Windows Azure and SQL Database Tutorials (en-US)]].
In addition to the properties required by the data model, every entity has two key properties: the PartitionKey and the RowKey. These properties together form the table's primary key and uniquely identify each entity in the table. Entities also have a Timestamp system property, which allows the service to keep track of when an entity was last modified.
The MessageBoardEntry.cs looks like the following (collapse to definitions) when completed:
Finally, you create a data source that can be bound to data controls in the ASP.NET web role that you will create in the next lesson.
To create a data source
using Microsoft.WindowsAzure; using Microsoft.WindowsAzure.StorageClient; using Microsoft.WindowsAzure.ServiceRuntime;
public class MessageBoardDataSource { }
private const string messageTableName = "MessageTable"; private const string connectionStringName = "DataConnectionString"; private static CloudStorageAccount storageAccount; private CloudTableClient tableClient;
public MessageBoardDataSource() { //add reference Microsoft.WindowsAzure.Configuration storageAccount = CloudStorageAccount.Parse( CloudConfigurationManager.GetSetting(connectionStringName)); // Create the table client tableClient = storageAccount.CreateCloudTableClient(); tableClient.RetryPolicy = RetryPolicies.Retry(3, TimeSpan.FromSeconds(1)); tableClient.CreateTableIfNotExist(messageTableName); }
The constructor initializes the storage account by reading its settings from the configuration files and then uses the CreateTablesIfNotExist method in the CloudTableClient class to create the table used by the application. You will configure DataConnectionString in Lesson 3.
public IEnumerable<MessageBoardEntry> GetEntries() { TableServiceContext tableServiceContext = tableClient.GetDataServiceContext(); var results = from g in tableServiceContext.CreateQuery<MessageBoardEntry>(messageTableName) where g.PartitionKey == DateTime.UtcNow.ToString("MMddyyyy") select g; return results; } public void AddEntry(MessageBoardEntry newItem) { TableServiceContext tableServiceContext = tableClient.GetDataServiceContext(); tableServiceContext.AddObject(messageTableName, newItem); tableServiceContext.SaveChanges(); }
The GetMessageBoardEntries method retrieves today's message board entries by constructing a LINQ statement that filters the retrieved information using the current date as the partition key value. The web role uses this method to bind to a data grid and display the message board.
The AddMessageBoardEntry method inserts new entries into the table.
The MessageBoardDataSource.cs looks like the following (collapse to definitions) when completed:
To compile the project
In this step, you created a data source that will be consumed by the ASP.Net web role that you will create in the next Lesson.
You will create an ASP.NET web role for displaying the message board and process user input.
In this lesson, you modify the web role project that you generated in Lesson 1 when you created the Windows Azure Cloud Service solution. This involves updating the UI to render the list of message board entries.
You must reference the MessageBoard_Data object from the web role project. To save time, you will begin with a skeleton default.aspx file.
To configure the web role project
The default.aspx file uses a DataList control and an ObjectDataSource control to display the messages. In the following procedure, you configure the two controls.
To modify Default.aspx
Note: If you get a message saying "The Type 'MessageBoard_Data.MessageBoardDataSource' could not be found", rebuild the solution and try again.
Next, you implement the code necessary to store submitted entries to the Table service.
To modify Default.aspx.cs
using MessageBoard_Data;
// create a new entry in the table MessageBoardEntry entry = new MessageBoardEntry() { GolferName = txtName.Text, GolferMessage = txtMessage.Text }; MessageBoardDataSource ds = new MessageBoardDataSource(); ds.AddEntry(entry); txtName.Text = ""; txtMessage.Text = ""; dlMessages.DataBind();
This method creates a new MessageBoardEntry entity, initializes it with the information submitted by the user, and then uses the MessageBoardDataSource class to save the entry to the table. Then, it refreshes its contents using the DataBind() method.
dlMessages.DataBind();
This method refreshes the page every 15 seconds. The refreshing interval is pre-configured in the default.aspx file.
if(!Page.IsPostBack) { tmrRefreshMsgs.Enabled = true; }
The code enables the page refresh timer.
Earlier in the tutorial, you defined a constant called connectionStringName, the value is DataConnectionString. DataConnectionString is a setting in the configuration file. You must define it. When you add a role to the Windows Azure project, Visual Studio generated two configuration files, ServiceConfiguration.Cloud.cscfg and ServiceConfiguration.Local.cscfg. You can configure the local configuration file to use the Storage Emulator for testing the application locally, and the cloud configuration file to use a Windows Azure storage account. Creating a storage account will be covered in lesson 5. For the time being, you configure both configuration files to use Storage Emulator.
Note: Storage Emulator offers local storage services that simulate the Blob, the Queue, and the Table services available in Windows Azure. The Storage Emulator UI provides a means to view the status of local storage service and to start, stop, and reset them. For more information, see Overview of the Windows Azure Storage Emulator at http://msdn.microsoft.com/en-us/library/gg432983.aspx.
To add the storage account settings
The DataConnectionString is used in the MessageBoardDataSource class you defined in Lesson 2.
In this step, you created a web role to display the message board and process user input.
You will test the application in the compute emulator. Then you will generate a service package that you can use to deploy the application to Windows Azure.
In this lesson, you test the message board application in the local compute emulator, and then deploy the application to Windows Azure as a cloud service. Note: The Windows Azure compute emulator simulates the Windows Azure fabric on your local computer so that you can run and test your service locally before deploying it. For more information, see Overview of the Windows Azure Compute Emulator at http://msdn.microsoft.com/en-us/library/gg432968.aspx.
To test the application
After the application is tested successfully in the compute emulator environment, the next step is to create the service package and then deploy the application to Windows Azure. Troubleshooting Here are several problems, along with suggested solutions, in case you encounter one of them.
Error: This access control list is not in canonical form and therefore cannot be modified. This exception may be thrown when the Windows Azure web role uses IIS instead of the Hosted Web Core (HWC). Here is an example of this error: http://social.msdn.microsoft.com/Forums/en-SG/windowsazuredevelopment/thread/07fe087e-4ac3-4c4f-bd62-4fccff4afd45 One solution, along with an explanation of the cause, is described here: New Full IIS Capabilities: Differences from Hosted Web Core In essence, you comment out the <Sites> node in the ServiceDefinition.csdef file. No connection could be made because the target machine actively refused it 127.0.0.1:10002 This error can be caused if the Azure Storage Emulator is pointing to the wrong instance of SQL Server on your computer. An example of this error is found here. You can use the DSInit command line tool to change which SQL Server instance the Azure Storage Emulator is pointing to. How to do this is described in How to Initialize the Storage Emulator by Using the DSInit Command-Line Tool
To generate the service package
You will get a few warning messages about 'DataConnectionString" set up to use the local storage emulator. You can ignore these warning for now.
For deploying the golfer message board application, you must have a storage account for accessing the Windows Azure storage services, and a cloud service, which is a container for service deployments in Windows Azure. For better performance, you might want to create an affinity group to group the service and the storage accounts within a subscription according to geo-location.
To sign in to Windows Azure
Note: If you haven’t had a Windows Azure Platform subscription, see the Provisioning Windows Azure section of this tutorial.
To create a storage account for the golfer message board application to store its data
To create a cloud service
Note: The URL prefix must be unique.
When you create and test the application locally, the application is configured to use the development storage. Now you have created a storage account, you can configure the application to use the stroage account before deploying the application to Windows Azure. The configuration information is in the ServiceConfiguration.Cloud.cscfg file. This file was created when you generated the service package.
To configure the ServiceConfiguration.Cloud.cscfg file
To deploy the application to the staging environment
To test the application in the staging environment
After the application is working correctly in the staging environment, you are ready to promote it to the production environment.
To promote the application to production
Note: Some DNS services take longer to replicate the records. If you get a page not found error, you might need to try browsing to the URL again in a few minutes.
In this step, you deployed the golfer message board to Windows Azure.
Congratulations! You have completed tutorial 1. Tutorials 2, 3 and 4 show you how to use SQL Database and other Windows Azure storage services.