CHAPTER 3 ■ WORKING WITH CLOUD QUEUE AND BLOB STORAGE 83 object in the message queue event handler. Figure 3-7 shows the screenshot of the Default.aspx page at runtime, and Figure 3-8 shows the results of using SQL Server Management Studio to query tables Accounts, AcctBlobContainerMap, BlobContainer, and Blob from the local DevelopmentStorageDb. The results show the structure of the relation between these tables and how the tables reference each other as we have presented in Figure 3-1 and Figure 3-2 at the beginning of this chapter. It also shows that access scope of the blob container has been set to public (a value of 1). Listing 3-10. Create a Blob to Store Information from a Message Sent from a Queue private void OnMessageReceive(object sender, EventArgs args) { Message message = (args as MessageReceivedEventArgs).Message; System.Diagnostics.Trace.WriteLine( string.Format( " {0}: OnMessageReceive, message = <{1}>", this.ToString(), message.ContentAsString() ) ); string blobName = string.Format("{0}{1}", message.Id, SUFFIX); if (! blobContainer.DoesBlobExist(blobName)) { BlobProperties properties = new BlobProperties(blobName); // Create metadata to be associated with the blob NameValueCollection metadata = new NameValueCollection(); metadata["MediaID"] = message.Id; properties.Metadata = metadata; properties.ContentType = "text/xml"; // Create the blob byte[] buffer = UTF8Encoding.UTF8 .GetBytes(message.ContentAsString().Replace("\r\n", string.Empty)); MemoryStream ms = new MemoryStream(buffer); BlobContents mediaBlob = new BlobContents(ms); blobContainer.CreateBlob(properties, mediaBlob, true); } DataBind(); } CHAPTER 3 ■ WORKING WITH CLOUD QUEUE AND BLOB STORAGE 84 Figure 3-7. Screenshot of the blob creating results CHAPTER 3 ■ WORKING WITH CLOUD QUEUE AND BLOB STORAGE 85 Figure 3-8. Quering results after blob storage records have been created To retrieve information stored in a blob, the BlobContainer class provides a set of access functions to query blobs in a blob container or the properties of a specific blob. The following are the steps to retrieve the information from a blob. 1. As Listing 3-11 shows, we create a C# container class called MediaInfo with three properties—BlobName, MediaUri, and MediaID—used to hold the information of a blob record. 2. In this exercise we define a GridView from the Default.aspx page to display the blob record as shown in the bold lines in Listing 3-12. The columns of the GridView bind to the properties of the MediaInfo class accordingly. For example, the DataTextField is bound to the property MediaID, and DataNavigateUrlFields is bound to MediaUri. CHAPTER 3 ■ WORKING WITH CLOUD QUEUE AND BLOB STORAGE 86 3. Use the instance blobContainer to call ListBlobs() and pass two parameters: prefix (an empty string in this exercise) and a boolean flag, CombineCommonPrefixs (false in this exercise). This function should return an instance of the IEnumerable type. 4. Loop through the collection of the blob record and populate the record into a local collection instance of mediaList with List<MediaInfo> type. 5. Assign the mediaList as the DataSource of the GridView and call the DataBind() method to bind the data to the GridView. By design, the call to ListBlobs() must occur prior to the call of GetBlobProperties(). Otherwise the call to GetBlobProperties() always returns a null object. Listing 3-11. Retrieving information from a blob public class MediaInfo { public MediaInfo(string blobName, string mediaAddress, string mediaID) { BlobName = blobName; MediaUri = mediaAddress; MediaID = mediaID; } public string MediaUri{get; set;} public string BlobName { get; set; } public string MediaID { get; set; } } private void DataBind() { IEnumerable<object> blobs = blobContainer.ListBlobs(string.Empty, false); List<MediaInfo> mediaList= new List<MediaInfo>(); foreach (object blob in blobs) { if ((blob as BlobProperties )!= null) { BlobProperties blobProperties = blobContainer.GetBlobProperties((blob as BlobProperties).Name); NameValueCollection mediaEntryProperties = blobProperties.Metadata; mediaList.Add( new MediaInfo( blobProperties.Name, CHAPTER 3 ■ WORKING WITH CLOUD QUEUE AND BLOB STORAGE 87 (blob as BlobProperties).Uri.ToString(), mediaEntryProperties["MediaID"] ) ); } } BlobLinksView.DataSource = filesList; BlobLinksView.DataBind(); } To delete a blob, the blob name needs to be passed as Listing 3-12 shows. In order to get the blob name, we need to insert a row command handler into the GridView from Default.aspx of this exercise as a linked button. To retrieve the specific blob item ID when the corresponding view item is clicked, a code behind handler RowCommandHandler should be inserted into Default.aspx.cs as Listing 3-13 shows. Listing 3-12. Pass Blob Name of the Blob Container Instance to Delete a Blob <asp:GridView id="BlobLinksView" DataKeyNames="BlobName" AllowPaging="False" AutoGenerateColumns="False" GridLines="Vertical" Runat="server" onrowcommand="RowCommandHandler" BackColor="#B3F2FD" ForeColor="Black" BorderColor="#0066FF" BorderStyle="None" BorderWidth="1px" CellPadding="4" Font-Size="Small" Width="394px"> <Columns> <asp:ButtonField Text="Delete" CommandName="DeleteEntry"/> <asp:HyperLinkField HeaderText="Blob ID" DataTextField="MediaID" DataNavigateUrlFields="MediaUri" /> </Columns> <RowStyle BackColor="#F7F7DE" /> <FooterStyle BackColor="#CCCC99" /> <PagerStyle BackColor="#F7F7DE" ForeColor="Black" HorizontalAlign="Right" /> <SelectedRowStyle BackColor="#CE5D5A" Font-Bold="True" ForeColor="White" /> <HeaderStyle BackColor="#6B696B" Font-Bold="True" ForeColor="White" /> <AlternatingRowStyle BackColor="White" /> </asp:GridView> protected void RowCommandHandler(object sender, GridViewCommandEventArgs e) { try {