Hands-On Lab
Exploring Windows Azure Storage
Lab version:1.0.0
Last updated:10/2/2018
Contents
Overview
Exercise 1: Working with Tables
Task 1 - Configuring Storage Account Settings
Task 2 - Creating Classes to Model the Table Schema
Task 3 - Creating the Chat User Interface
Verification
Exercise 2: Working with Blobs
Task 1 – Retrieving Blob Data from Storage
Task 2 – Uploading Blob Data to Storage
Task 3 – Retrieving Metadata for Blobs in Storage
Task 4 – Deleting Blobs from Storage
Task 5 – Copy Blobs
Verification
Task 6 – Snapshot Blobs
Verification
Exercise 3: Working with Queues
Task 1 – Creating the Initial Solution
Task 2 – Sending Messages to the Queue
Task 3 – Retrieving Messages from the Queue
Verfication
Summary
Overview
Storage services provide persistent, durable storage in the Windows Azure fabric, and include blob and table storage and the queue service.
In this lab, you will examine the basic process of working with Windows Azurestorage on the local development fabric, and explore some of the features that are available to developers.
Objectives
In this Hands-On Lab, you will learn how to:
- Use tables
- Use blob storage
- Use queues
- Create and read metadata
Prerequisites
The following is required to complete this hands-on lab:
- IIS 7 (with ASP.NET, WCF HTTP Activation, Tracing)
- Microsoft .NET Framework 3.5 SP1
- Microsoft Visual Studio 2008 SP1 (or above)
- SQL Server 2005 Express Edition (or above)
- Windows Azure Tools for Microsoft Visual Studio (November 2009)
Setup
For convenience, much of the code used in this hands-on lab is available as Visual Studio code snippets. To check the prerequisites of the lab and install the code snippets:
- Run the SetupLab.cmd script located in the lab's Source\Setup folder to check dependencies and install any missing prerequisites.
- Once you have verified every prerequisite, follow the instructions to install the code snippets.
Using the Code Snippets
With code snippets, you have all the code you need at your fingertips. The lab document will tell you exactly when you can use them. For example,
To add this code snippet in Visual Studio, you simply place the cursor where you would like the code to be inserted, start typing the snippet name (without spaces or hyphens), in this case LabNameEx01RunmethodCS, watch as Intellisense picks up the snippet name, and then hit the TAB key twice once the snippet you want is selected. The code will be inserted at the cursor location.
Figure 1
Hit TAB to select the highlighted snippet.
Figure 2
Hit TAB again and the snippet will expand
To insert a code snippet using the mouse rather than the keyboard, right-click where you want the code snippet to be inserted, select Insert Snippetfollowed by My Code Snippetsand then pick the relevant snippet from the list.
To learn more about Visual Studio IntelliSense Code Snippets, including how to create your own, please see
Exercises
This Hands-On Lab comprises the following exercises:
- Working with Tables
- Working with Blobs
- Working with Queues
Estimated time to complete this lab: 90 minutes.
Exercise 1: Working with Tables
In this exercise, you use the Windows Azure Table Storage API to create a simple application that stores and retrieves data in structured storage. It consists of a simple chat Web application that can save, retrieve and display messages stored in a Windows Azure table.
Windows Azure tables store data as collections of entities. Entities are similar to rows. An entity has a primary key and a set of properties. A property is a name/value pair, similar to a column.
To access Windows Azure Table Storage, you use a REST API that is compatible with the ADO.NET Data Services Framework. This exercise uses the .NET Client Library (ADO.NET Data Services Framework) to read and write data to table storage.
Task 1 - Configuring Storage Account Settings
In this task, you configure the settings required to make a connection to the Table Storage Service.
- Open Microsoft Visual Studio 2008 elevated as Administrator from Start | All Programs | Microsoft Visual Studio 2008 by right-clicking Microsoft Visual Studio 2008 and choosing Run as Administrator.
- In the File menu, choose Open and then Project/Solution. In the Open Project dialog, browse to Ex01-WorkingWithTables\Begin in the Source folder of this lab, select the folder for your preferred language and open theBegin.slnfile.
Figure 1
Solution Explorer showing the Windows Azure Chat application
Note: The solution contains a Windows Azure WebRole project.
- Make sure RdChat is the start up project by right clicking on it and select Set as StartUp Project.
Figure 2
Set StartUp Project
- Update the service definition file to define the configuration settings required to access Windows Azure Table storage. In Solution Explorer, right-click the RdChat_WebRole role under the Roles folder.
Figure 3
Launching the Service Configuration Editor
- Select the Settings Tab, click Add Setting and create a new configuration setting called DataConnectionString. Set the type to ConnectionString, then click the ellipses icon and configure the storage connection string to Use development storage.
Figure 4
Creating a DataConnectionString
Figure 5
Configure Connection String to use Development Storage
- Press CTRL-S to save your configuration changes.
Note: The StorageClient library uses these settings to access Windows Azure Storage.
DataConnectionString: This is the connection string to the Window Azure account, through which we can programmatically access data storage and other functionalities in Windows Azure. This connection string can point to a Windows Azure Account in the cloud as well as local development fabric.
DiagnosticsConnectionString: This is the connection string to Windows Azure server, same as DataConnectionString, however this one is dedicated for logging diagnostics.
Task 2 - Creating Classes to Model the Table Schema
When working locally against the development storage service for Table Storage,you use the ADO.NET client library.
To use Windows Azure table storage in .NET, you construct a class that models the desired schema. In addition to the properties required by your model, the classmust include a Timestamp, a PartitionKey and a RowKey property and it must be decorated with aDataServiceKey(“PartitionKey”, “RowKey”) custom attribute. To simplify this, the Microsoft.WindowsAzure. StorageClient namespace includes a TableServiceEntity class that already defines the mandatory properties and attribute and can easily be derived from in your class.
In this task, you will create the modelwhere the data and will be stored for the Chat application.
- Add a reference to the ADO.NET client library to the Web role project. In Solution Explorer, right-click the RdChat_WebRole project node and select Add Reference. In the .NET tab, select the System.Data.Services.Client assembly and click OK.
- Add a class to the Web role project to model the message table. To do this, in Solution Explorer, right-click the RdChat_WebRole project node, point to Add and select Class. In the Add New Item dialog, set the Name to Message.cs/ Message.vband click Add.
- Update the declaration of the Message class to derive from the Microsoft.WindowsAzure.StorageClient.TableServiceEntity class.
(Code Snippet – ExploringWindowsAzureStorage-Ex01-01-MessageClass-CS)
C#
public class Message: Microsoft.WindowsAzure.StorageClient.TableServiceEntity
{
}
(Code Snippet – ExploringWindowsAzureStorage-Ex01-01-MessageClass-VB)
Visual Basic
Public Class Message
Inherits Microsoft.WindowsAzure.StorageClient.TableServiceEntity
End Class
Note: The TableServiceEntityclass is included as part of the Microsoft.WindowsAzure.StorageClient library. It defines the PartititionKey, RowKey and TimeStamp system properties required by every entity stored in a Windows Azure table.
Together, the PartitionKey and RowKey define the DataServiceKey that uniquely identifies every entity within a table.
- Add a default constructor to the Message class that initializes its PartitionKey and RowKey properties.
(Code Snippet – ExploringWindowsAzureStorage-Ex01-02-MessageConstructor-CS)
C#
public Message()
{
PartitionKey = "a";
RowKey = string.Format("{0:10}_{1}", DateTime.MaxValue.Ticks - DateTime.Now.Ticks, Guid.NewGuid());
}
(Code Snippet – ExploringWindowsAzureStorage-Ex01-02-MessageConstructor-VB)
Visual Basic
Public Sub New()
PartitionKey = "a"
RowKey = String.Format("{0:10}_{1}", (DateTime.MaxValue.Ticks - DateTime.Now.Ticks), Guid.NewGuid)
End Sub
Note: For the purposes of this exercise, you assign a fixed value to the PartitionKey property. In a more realistic scenario, you would choose a value that ensures load balancing across storage nodes.
- Add two string properties to the Message class, Name and Body, to hold information about the chat message.
(Code Snippet – ExploringWindowsAzureStorage-Ex01-03-TableSchemaProperties-CS)
C#
public string Name { get; set; }
public string Body { get; set; }
(Code Snippet – ExploringWindowsAzureStorage-Ex01-03-TableSchemaProperties-VB)
Visual Basic
Private _body As String
Private _name As String
Public Property Body() As String
Get
Return _body
End Get
Set(ByVal value As String)
_body = value
End Set
End Property
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
- Save the Message.cs/ Message.vbfile.
- Next, add a class to the Web role project to define the ADO.NET DataServiceContext required to access the Messages table. To do this, in Solution Explorer, right-click the RdChat_WebRole project node, point to Add and select Class. In the Add New Item dialog, set the Name to MessageDataServiceContext.cs/ MessageDataServiceContext.vband click Add.
- In the new class file, add the following using namespace directives.
(Code Snippet – ExploringWindowsAzureStorage-Ex01-04-Namespace-CS)
C#
using Microsoft.WindowsAzure.StorageClient;
using Microsoft.WindowsAzure;
(Code Snippet – ExploringWindowsAzureStorage-Ex01-04-Namespace-VB)
Visual Basic
Imports Microsoft.WindowsAzure.StorageClient
Imports Microsoft.WindowsAzure
- Replace the declaration of the new class to derive from theTableServiceContextclass and include a default constructor to initialize the base class with the storage account information.
(Code Snippet – ExploringWindowsAzureStorage-Ex01-05-MessageDataServiceContextClass-CS)
C#
namespace RdChat_WebRole
{
public class MessageDataServiceContext : TableServiceContext
{
public MessageDataServiceContext(string baseAddress, StorageCredentials credentials)
: base(baseAddress, credentials)
{
}
}
}
(Code Snippet – ExploringWindowsAzureStorage-Ex01-05-MessageDataServiceContextClass-VB)
Visual Basic
Public Class MessageDataServiceContext
Inherits TableServiceContext
' Methods
Public Sub New(ByVal baseAddress As String, ByVal credentials As StorageCredentials)
MyBase.New(baseAddress, credentials)
End Sub
End Class
- Now, add a property to the MessageDataServiceContext class to return a data service query for the Messages table.
(Code Snippet – ExploringWindowsAzureStorage-Ex01-06-MessagesProperty-CS)
C#
public IQueryable<Message> Messages
{
get
{
return this.CreateQuery<Message>("Messages");
}
}
(Code Snippet – ExploringWindowsAzureStorage-Ex01-06-MessagesProperty-VB)
Visual Basic
Public ReadOnly Property Messages() As IQueryable(Of Message)
Get
Return MyBase.CreateQuery(Of Message)("Messages")
End Get
End Property
Note: Visual Studio identifies classes that derive from DataServiceContext in the solution and locates any properties that return an IQueryable<T, where the generic parameter T identifies the class that models the table schema. For each such property, it creates a table in local development storage named after the property and defines its schema using the public properties in the model class.
- Finally, add a method to the MessageDataServiceContext class to insert new messages into the table. You will use this method later when implementing the chat functionality.
(Code Snippet – ExploringWindowsAzureStorage-Ex01-07-AddMessageMethod-CS)
C#
public void AddMessage(string name, string body)
{
this.AddObject("Messages", new Message { Name = name, Body = body });
this.SaveChanges();
}
(Code Snippet – ExploringWindowsAzureStorage-Ex01-07-AddMessageMethod-VB)
Visual Basic
Public Sub AddMessage(ByVal name As String, ByVal body As String)
Dim message As New Message
message.Name = name
message.Body = body
MyBase.AddObject("Messages", message)
MyBase.SaveChanges()
End Sub
- In the Build menu, select Build Solution.
Task 3 - Creating the Chat User Interface
In this task, you add the code necessary to store messages in a Windows Azure table and display them on the Web page.
- Locate the OnStart method in WebRole.cs/ WebRole.vbfile and insert the following code (shown in bold, andhighlighted) to this method directly above the line return base.OnStart();(C#)or Return MyBase.OnStart()(VB)This creates storage tables from MessageDataServiceContext that we created earlier.
(Code Snippet – ExploringWindowsAzureStorage-Ex01-09-PageLoadMethod-CS)
C#
public override bool OnStart()
{
DiagnosticMonitor.Start("DiagnosticsConnectionString");
RoleEnvironment.Changing += RoleEnvironmentChanging;
CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
{
configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));
RoleEnvironment.Changed += (anotherSender, arg) =>
{
if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
.Any((change) => (change.ConfigurationSettingName == configName)))
{
if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))
{
RoleEnvironment.RequestRecycle();
}
}
};
});
var account = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
CloudTableClient.CreateTablesFromModel(typeof(MessageDataServiceContext),
account.TableEndpoint.AbsoluteUri, account.Credentials);
return base.OnStart();
}
(Code Snippet – ExploringWindowsAzureStorage-Ex01-09-PageLoadMethod-VB)
Visual Basic
Public Overrides Function OnStart() As Boolean
DiagnosticMonitor.Start("DiagnosticsConnectionString")
AddHandler RoleEnvironment.Changing, AddressOf RoleEnvironmentChanging
CloudStorageAccount.SetConfigurationSettingPublisher(AddressOf ConfigurationSettingPublisher)
Dim account As CloudStorageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString")
CloudTableClient.CreateTablesFromModel(GetType(MessageDataServiceContext), account.TableEndpoint.AbsoluteUri, account.Credentials)
Return MyBase.OnStart()
End Function
When executed in the cloud, the code creates the required tables from the model defined by the MessageDataServiceContext class created earlier.
Note that it is recommendedthat data tables should be only created once and is typically done as a provisioning step and rarely in application code. The OnStart method in WebRole class is a recommended place for this initialization logic.
To retrieve and display messages, the method creates an instance of the MessageDataServiceContext class and initializes it from account information available in the service configuration file (ServiceConfiguration.cscfg). It binds the Messages property, which returns a data service query for the Messages table, to a ListView control on the page for display.
Note: Objects of type CloudStorageAccount represent a storage account, which contains the settings required to make a connection to the Storage Service. Associated with a storage account are the account name, the URI of the account and a shared key, which the CloudTableClient helper class uses for its initialization. These settings are obtained from ServiceConfiguration.cscfg.
- Open the code-behind file for the Web page that contains the UI for the chat application. Expand the RDChat_WebRole node in Solution Explorer, then right-click Default.aspx and select View Code.
Make sure the following using namespace directives are in the Default.aspx.cs / Default.aspx.vb.
(Code Snippet – ExploringWindowsAzureStorage-Ex01-08-Namespace-CS)
C#
using Microsoft.WindowsAzure;
using System.Data.Services.Client;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;
(Code Snippet – ExploringWindowsAzureStorage-Ex01-08-Namespace-VB)
Visual Basic
Imports Microsoft.WindowsAzure.ServiceRuntime
Imports Microsoft.WindowsAzure.StorageClient
Imports Microsoft.WindowsAzure
Imports System.Data.Services.Client
- Locate the SubmitButton_Click event handlerin Default.aspx.cs/Default.aspx.vb and insert the following code (shown in bold, andhighlighted)into the method body to save messages entered by the user to the Table Storage, thendata bind messages from Table Storage to the page. The method uses the AddMessage method, which you created earlier in the lab, to insert a new Message entity into the table.
(Code Snippet – ExploringWindowsAzureStorage-Ex01-10-SubmitButtonClick-CS)
C#
protected void SubmitButton_Click(object sender, EventArgs e)
{
var statusMessage = String.Empty;
try
{
var account = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
var context = new MessageDataServiceContext(account.TableEndpoint.ToString(), account.Credentials);
context.AddMessage(this.nameBox.Text, this.messageBox.Text);
this.messageList.DataSource = context.Messages;
this.messageList.DataBind();
}
catch (DataServiceRequestException ex)
{
statusMessage = "Unable to connect to the table storage server. Please check that the service is running.<br>"
+ ex.Message;
}
status.Text = statusMessage;
}
(Code Snippet – ExploringWindowsAzureStorage-Ex01-10-SubmitButtonClick-VB)
Visual Basic
Protected Sub SubmitButton_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim statusMessage As String = String.Empty
Try
Dim account As CloudStorageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString")
Dim context As New MessageDataServiceContext(account.TableEndpoint.ToString, account.Credentials)
context.AddMessage(Me.nameBox.Text, Me.messageBox.Text)
Me.messageList.DataSource = context.Messages
Me.messageList.DataBind()
Catch ex As DataServiceRequestException
statusMessage = ("Unable to connect to the table storage server. Please check that the service is running.<br>" & ex.Message)
End Try
Me.status.Text = statusMessage
End Sub
- Save the all files and select Build Solutionfrom the Build menu.
Verification
To test your service running in the development fabric:
- In Visual Studio, press F5 to build and run the application. The development fabric starts and a new tenant containing the RdChat Web Role initializes. A browser window opens to display the Windows Azure Chat Web page.
Figure 6
Application after connecting successfully to the development storage table server
When you start the program in the debugger, Visual Studio automatically starts Development Storage Services. If the Chat application is unable to access the table storage server, you will see an error as shown in the figure below. To examine the status of the service, right-click the icon in the system tray (it looks like a server) and select Show Development Storage UI.
Figure 7
Viewing the status of development storage
- Now, test the Chat application by entering a few messages. Type your name and the text of your message and click Submit. The page uses AJAX calls to constantly poll the server and retrieve new messages. Wait a few seconds for the browser window to update and show your message.
- In Internet Explorer, press Ctrl + N to open a second browser window. Enter a different name and type a few more messages. Notice how both windows update to show the conversation.