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 4, 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 4. 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.
A great article to start with.
In Lesson 5 there is mention to the folder: C:\AzureTutorials\Tutorial1\TutorialFiles\ folder to add Default.aspx file to the webrole project. It would be great that this is attached in the article for download. When I tried this tutorial by writing my own Default.aspx page I'm getting the below error
<error xmlns="schemas.microsoft.com/.../metadata">
<code>ResourceNotFound</code>
SeanaLS,
"Windows Azure Technologies Tutorials" (social.technet.microsoft.com/.../windows-azure-technologies-tutorials.aspx) has the steps for configuring the environment and downloading the tutorial files.
I will make a note to this article.
hey getting error after building (lesson 2) Error 1 The name 'MessageTableName' does not exist in the current context C:\AzureTutorials\tutorial1\MessageBoard_Data\MessageBoard_Data\MessageBoardDataSource.cs 24 47 MessageBoard_Data
Error 2 The name 'MessageTableName' does not exist in the current context C:\AzureTutorials\tutorial1\MessageBoard_Data\MessageBoard_Data\MessageBoardDataSource.cs 29 88 MessageBoard_Data
Error 3 The name 'context' does not exist in the current context C:\AzureTutorials\tutorial1\MessageBoard_Data\MessageBoard_Data\MessageBoardDataSource.cs 38 13 MessageBoard_Data
Error 4 The name 'context' does not exist in the current context C:\AzureTutorials\tutorial1\MessageBoard_Data\MessageBoard_Data\MessageBoardDataSource.cs 39 13 MessageBoard_Data
Mohit,
Thank you for your feedback. There are several typos in the code sections. I just fixed the typos. The code snippets appear OK.
Please follow these steps to fix the problems:
1. From your project within Visual Studio, search "MessageTableName" with the case sensitive option. You will find two appearances. Replace both of them with "messageTableName".
2. From your project within Visual Studio, search "context." (there is a full stop at the end). You shall find two appearances. Replace both of them with "tableServiceContext.".
Let me know if you have any other questions. You can also send email to azure@microsoft.com.
Jonathan
Great article, Jonathan!
Hey, just a possibly dumb questions from an Azure newbie. I created a solution, using Entity Model First in my data model. I have run the generated database scripts on my SQL Azure database. Another console application project calls the data model, which uses an Azure connection string to do its database operations.
That's all working fine, without adding an actual Azure project or a web/worker role to my solution, and without worrying about partition or row keys. Not a real difference to using SQL Server, apart from adding a retry logic.
Am I missing something completely, or have I done right?
Rudi
Rudi, thank you for trying the tutorial and providing feedback. You are on the right track. The tutorial 2 demonstrates calling SQL Azure from a web role. You can also consume SQL Azure directly from your own application. Apparently, using web role can reduce possible network issues. For more information, see social.technet.microsoft.com/.../sql-azure-connection-management-in-sql-azure.aspx.
i ant to download the sour code . hoqw can i download? i am not able to find out the link.
i downloaded the example as stated above complete , build and set the startup project as stated but when i debug the application and run it takes alot of time to run and after that displays the message board. I enter the details and click on send button as soon as i click on the button it raisses the error of:
Microsoft JScript runtime error: 'WebForm_DoPostBackWithOptions' is undefined
on Defualt.aspx
Why this is raisisng the error?
Hello ArchanaSinghvi, I haven't seen this error. Have you tried the completed solution in the C:\AzureTutorials\Tutorial1\CompletedSolution folder? Do you get the same error?