Developing Cloud Applications with Windows Azure Storage: Blobs

  • 3/15/2013

Blob attributes and metadata

Containers and blobs support two types of ancillary data: system properties and user-defined metadata. System properties exist on every blob and blob container. Some properties are read-only, whereas others can be set. A few of them correspond to specific standard HTTP headers, which the Windows Azure SDK will maintain for you. User-defined metadata allows you to define supplementary name-value dictionary information about the blob container or the blob. As its name implies, metadata should be used to store data about your data (not the data itself). This can sometimes be a matter of perspective.

Blob containers have attributes that describe both the containers’ URI and Name. Each container has two read-only properties: LastModifiedUtc, which is the UTC time that the blob container was last updated; and ETag, which is a version number used for optimistic concurrency. Blob containers also provide 8 KB of customizable metadata in the form of a name-value pair dictionary, which you can use for your own purposes. Metadata should be used to store information about the blob or the blob’s container. For example, you might store the name of the person who last read the contents of a blob in its metadata, and possibly the date and time the access was made.

The following HTTP PUT request demonstrates how to set metadata values. The query string comp=metadata sets up the operation. The values for the metadata are transmitted via HTTP x-ms-meta-<name> headers, where <name> is the name you are giving your metadata, and the value of the HTTP header is the value of your named metadata. The following example shows this.

x-ms-version: 2012-02-12
User-Agent: WA-Storage/2.0.0
x-ms-meta-CreatedBy: Paul
x-ms-meta-SourceMachine: DILITHIUM
x-ms-date: Tue, 18 Dec 2012 07:05:23 GMT
Authorization: SharedKey azureinsiders:02TWst4Dx5Qgr0zq31w7AvENcc+OezO6+HobJ4qZMlY=
Content-Length: 0

The following code demonstrates how to use the Windows Azure client library to store metadata containing the person’s name and the machine that person was using when they created the blob.

container.SetPermissions(new BlobContainerPermissions() {
PublicAccess = BlobContainerPublicAccessType.Container });
CloudBlob blob = container.GetBlobReference("ReadMe.txt");
blob.UploadText("This is some text");
blob.Attributes.Metadata["CreatedBy"] = "Paul";
blob.Metadata["SourceMachine"] = Environment.MachineName;
// NOTE: SetMetadata & SetProperties update the blob's ETag & LastModifiedUtc

When you launch Internet Explorer on the blob’s URL, the contents of the blob are displayed. Similar to what you did previously, you can launch a browser directly against the blob container’s URL, passing the filtration criteria ?restype=container&comp=list&include=metadata in the query string. The following code will launch Internet Explorer to list the contents of the blob container, including its properties and any metadata.

// Get blobs in container showing each blob's properties & metadata
// See for more options
Process.Start("IExplore", container.Uri +

You can also retrieve a list of blobs, including properties and metadata, programmatically using the Windows Azure client library. First, pass an instance of BlobRequestOptions with its BlobListingDetails property set to BlobListingDetails.Metadata. Then call the FetchAttributes method on the blob proxy. The FetchAttributes method will include properties and metadata.

container.ListBlobs(new BlobRequestOptions {
    BlobListingDetails = BlobListingDetails.Metadata });

The following code then loops through the collection of the blob’s properties and metadata and displays the corresponding value for each.

// Read the blob's attributes (which include properties & metadata)
BlobProperties p = blob.Properties;
Console.WriteLine("Blob's metadata (LastModifiedUtc={0}, ETag={1})",
         p.LastModifiedUtc, p.ETag);

Console.WriteLine("   Content Type={0}, Encoding={1}, Language={2}, MD5={3}",
   p.ContentType, p.ContentEncoding, p.ContentLanguage, p.ContentMD5);
foreach (String keyName in blob.Metadata.Keys)
   Console.WriteLine("   {0} = {1}", keyName, blob.Metadata[keyName]);