Windows Azure ストレージ サービス REST API を直接使うコード サンプル

更新日:

Windows Azure ストレージ サービス REST API を直接使うコード サンプル が公開されています。

http://convective.wordpress.com/2010/08/18/examples-of-the-windows-azure-storage-services-rest-api/

以下、上記URLから本文を引用して紹介します。

In the Windows Azure MSDN Azure Forum there are occasional questions about the Windows Azure Storage Services REST API. I have occasionally responded to these with some code examples showing how to use the API. I thought it would be useful to provide some examples of using the REST API for tables, blobs and queues – if only so I don’t have to dredge up examples when people ask how to use it. This post is not intended to provide a complete description of the REST API.

The REST API is comprehensively documented (other than the lack of working examples). Since the REST API is the definitive way to address Windows Azure Storage Services I think people using the higher level Storage Client API should have a passing understanding of the REST API to the level of being able to understand the documentation. Understanding the REST API can provide a deeper understanding of why the Storage Client API behaves the way it does.

Fiddler

The Fiddler Web Debugging Proxy is an essential tool when developing using the REST (or Storage Client) API since it captures precisely what is sent over the wire to the Windows Azure Storage Services.

Authorization

Nearly every request to the Windows Azure Storage Services must be authenticated. The exception is access to blobs with public read access. The supported authentication schemes for blobs, queues and tables and these are described here. The requests must be accompanied by an Authorization header constructed by making a hash-based message authentication code using the SHA-256 hash.

The following is an example of performing the SHA-256 hash for the Authorization header

private String CreateAuthorizationHeader(String canonicalizedString)
{
    String signature = string.Empty;
    using (HMACSHA256 hmacSha256 = new HMACSHA256(AzureStorageConstants.Key))
    {
        Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(canonicalizedString);
        signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
    }

    String authorizationHeader = String.Format(
          CultureInfo.InvariantCulture,
          "{0} {1}:{2}",
          AzureStorageConstants.SharedKeyAuthorizationScheme,
          AzureStorageConstants.Account,
          signature);

    return authorizationHeader;
}

This method is used in all the examples in this post.

AzureStorageConstants is a helper class containing various constants. Key is a secret key for Windows Azure Storage Services account specified by Account. In the examples given here, SharedKeyAuthorizationScheme is SharedKey.

The trickiest part in using the REST API successfully is getting the correct string to sign. Fortunately, in the event of an authentication failure the Blob Service and Queue Service responds with the authorization string they used and this can be compared with the authorization string used in generating the Authorization header. This has greatly simplified the us of the REST API.

Table Service API

The Table Service API supports the following table-level operations:

The Table Service API supports the following entity-level operations:

These operations are implemented using the appropriate HTTP VERB:

  • DELETE – delete
  • GET – query
  • MERGE – merge
  • POST – insert
  • PUT – update

This section provides examples of the Insert Entity and Query Entities operations.

Insert Entity

The InsertEntity() method listed in this section inserts an entity with two String properties, Artist and Title, into a table. The entity is submitted as an ATOM entry in the body of a request POSTed to the Table Service. In this example, the ATOM entry is generated by the GetRequestContentInsertXml() method. The date must be in RFC 1123 format in the x-ms-date header supplied to the canonicalized resource used to create the Authorization string. Note that the storage service version is set to “2009-09-19” which requires the DataServiceVersion and MaxDataServiceVersion to be set appropriately.

private void InsertEntity(String tableName, String artist, String title)
{
    String requestMethod = "POST";

    String urlPath = tableName;

    String storageServiceVersion = "2009-09-19";

    String dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
    String contentMD5 = String.Empty;
    String contentType = "application/atom+xml";
    String canonicalizedResource = String.Format("/{0}/{1}", AzureStorageConstants.Account, urlPath);
    String stringToSign = String.Format(
          "{0}n{1}n{2}n{3}n{4}",
          requestMethod,
          contentMD5,
          contentType,
          dateInRfc1123Format,
          canonicalizedResource);
    String authorizationHeader = CreateAuthorizationHeader(stringToSign);

    UTF8Encoding utf8Encoding = new UTF8Encoding();
    Byte[] content = utf8Encoding.GetBytes(GetRequestContentInsertXml(artist, title));

    Uri uri = new Uri(AzureStorageConstants.TableEndPoint + urlPath);
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    request.Accept = "application/atom+xml,application/xml";
    request.ContentLength = content.Length;
    request.ContentType = contentType;
    request.Method = requestMethod;
    request.Headers.Add("x-ms-date", dateInRfc1123Format);
    request.Headers.Add("x-ms-version", storageServiceVersion);
    request.Headers.Add("Authorization", authorizationHeader);
    request.Headers.Add("Accept-Charset", "UTF-8");

    request.Headers.Add("DataServiceVersion", "1.0;NetFx");
    request.Headers.Add("MaxDataServiceVersion", "1.0;NetFx");

    using (Stream requestStream = request.GetRequestStream())
    {
        requestStream.Write(content, 0, content.Length);
    }

    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        Stream dataStream = response.GetResponseStream();
        using (StreamReader reader = new StreamReader(dataStream))
        {
            String responseFromServer = reader.ReadToEnd();
        }
    }
}

private String GetRequestContentInsertXml(String artist, String title)
{
    String defaultNameSpace = "http://www.w3.org/2005/Atom";
    String dataservicesNameSpace = "http://schemas.microsoft.com/ado/2007/08/dataservices";
    String metadataNameSpace = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";

    XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
    xmlWriterSettings.OmitXmlDeclaration = false;
    xmlWriterSettings.Encoding = Encoding.UTF8;

    StringBuilder entry = new StringBuilder();
    using (XmlWriter xmlWriter = XmlWriter.Create(entry))
    {
        xmlWriter.WriteProcessingInstruction("xml", "version="1.0" encoding="UTF-8"");
        xmlWriter.WriteWhitespace("n");
        xmlWriter.WriteStartElement("entry", defaultNameSpace);
        xmlWriter.WriteAttributeString("xmlns", "d", null, dataservicesNameSpace);
        xmlWriter.WriteAttributeString("xmlns", "m", null, metadataNameSpace);
        xmlWriter.WriteElementString("title", null);
        xmlWriter.WriteElementString("updated", String.Format("{0:o}", DateTime.UtcNow));
        xmlWriter.WriteStartElement("author");
        xmlWriter.WriteElementString("name", null);
        xmlWriter.WriteEndElement();
        xmlWriter.WriteElementString("id", null);
        xmlWriter.WriteStartElement("content");
        xmlWriter.WriteAttributeString("type", "application/xml");
        xmlWriter.WriteStartElement("properties", metadataNameSpace);
        xmlWriter.WriteElementString("PartitionKey", dataservicesNameSpace, artist);
        xmlWriter.WriteElementString("RowKey", dataservicesNameSpace, title);
        xmlWriter.WriteElementString("Artist", dataservicesNameSpace, artist);
        xmlWriter.WriteElementString("Title", dataservicesNameSpace, title + "n" + title);
        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndElement();
        xmlWriter.Close();
    }
    String requestContent = entry.ToString();
    return requestContent;
}

This generates the following request (as captured by Fiddler):

POST http://myaccount.table.core.windows.net/Novel HTTP/1.1
Accept: application/atom+xml,application/xml
Content-Type: application/atom+xml
x-ms-date: Tue, 17 Aug 2010 23:43:30 GMT
x-ms-version: 2009-09-19
Authorization: SharedKey myaccount:CGh+pI+kJamesBond007h6bze5pTUQ33uY9FI8yrPljY/ORU=
Accept-Charset: UTF-8
DataServiceVersion: 1.0;NetFx
MaxDataServiceVersion: 1.0;NetFx
Host: myaccount.table.core.windows.net
Content-Length: 506
Expect: 100-continue

The body of the request is:

<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom"><title /><updated>2010-08-17T23:43:30.2967813Z</updated><author><name /></author><id /><content type="application/xml"><m:properties><d:PartitionKey>Beckett</d:PartitionKey><d:RowKey>Molloy</d:RowKey><d:Artist>Beckett</d:Artist><d:Title>Molloy</d:Title></m:properties></content></entry>

The Table Service generates the following response:

HTTP/1.1 201 Created
Cache-Control: no-cache
Content-Type: application/atom+xml;charset=utf-8
ETag: W/"datetime’2010-08-17T23%3A43%3A26.1913755Z’"
Location: http://myaccount.table.core.windows.net/Novel(PartitionKey=’Beckett’,RowKey=’Molloy’)
Server: Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: 8d19dbe9-9346-4a3a-9853-9a8c8fc49aeb
x-ms-version: 2009-09-19
Date: Tue, 17 Aug 2010 23:43:25 GMT
Content-Length: 1097

The Table Service generates the following response body: 

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<entry xml:base=http://myaccount.table.core.windows.net/ xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:etag="W/&quot;datetime’2010-08-17T23%3A43%3A26.1913755Z’&quot;" xmlns="http://www.w3.org/2005/Atom">
  <id>http://myaccount.table.core.windows.net/Novel(PartitionKey=’Beckett’,RowKey=’Molloy’)</id>
  <title type="text"></title>
  <updated>2010-08-17T23:43:26Z</updated>
  <author>
    <name />
  </author>
  <link rel="edit" title="Novel" href="Novel(PartitionKey=’Beckett’,RowKey=’Molloy’)" />
  <category term="myaccount.Novel" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
  <content type="application/xml">
    <m:properties>
      <d:PartitionKey>Beckett</d:PartitionKey>
      <d:RowKey>Molloy</d:RowKey>
      <d:Timestamp m:type="Edm.DateTime">2010-08-17T23:43:26.1913755Z</d:Timestamp>
      <d:Artist>Beckett</d:Artist>
      <d:Title>Molloy</d:Title>
    </m:properties>
  </content>
</entry>

Note that I should have URLEncoded the PartitionKey and RowKey but did not do so for simplicity. There are, in fact, some issues with the URL encoding of spaces and other symbols.

Get Entity

The GetEntity() method described in this section retrieves the single entity inserted in the previous section. The particular entity to be retrieved is identified directly in the URL.

private void GetEntity(String tableName, String partitionKey, String rowKey)
{
    String requestMethod = "GET";

    String urlPath = String.Format("{0}(PartitionKey=’{1}’,RowKey=’{2}’)", tableName, partitionKey, rowKey);

    String storageServiceVersion = "2009-09-19";

    String dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
    String canonicalizedResource = String.Format("/{0}/{1}", AzureStorageConstants.Account, urlPath);
    String stringToSign = String.Format(
          "{0}nnn{1}n{2}",
          requestMethod,
          dateInRfc1123Format,
          canonicalizedResource);
    String authorizationHeader = CreateAuthorizationHeader(stringToSign);

    Uri uri = new Uri(AzureStorageConstants.TableEndPoint + urlPath);
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    request.Method = requestMethod;
    request.Headers.Add("x-ms-date", dateInRfc1123Format);
    request.Headers.Add("x-ms-version", storageServiceVersion);
    request.Headers.Add("Authorization", authorizationHeader);
    request.Headers.Add("Accept-Charset", "UTF-8");
    request.Accept = "application/atom+xml,application/xml";

    request.Headers.Add("DataServiceVersion", "1.0;NetFx");
    request.Headers.Add("MaxDataServiceVersion", "1.0;NetFx");

    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        Stream dataStream = response.GetResponseStream();
        using (StreamReader reader = new StreamReader(dataStream))
        {
            String responseFromServer = reader.ReadToEnd();
        }
    }
}

This generates the following request (as captured by Fiddler):

GET http://myaccount.table.core.windows.net/Novel(PartitionKey=’Beckett’,RowKey=’Molloy’) HTTP/1.1
x-ms-date: Tue, 17 Aug 2010 23:43:31 GMT
x-ms-version: 2009-09-19
Authorization: SharedKey myaccount:CGh+pI+kJamesBond007h6bze5pTUQ33uY9FI8yrPljY/ORU=
Accept-Charset: UTF-8
Accept: application/atom+xml,application/xml
DataServiceVersion: 1.0;NetFx
MaxDataServiceVersion: 1.0;NetFx
Host: myaccount.table.core.windows.net

The Table Service generates the following response:

HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Type: application/atom+xml;charset=utf-8
ETag: W/"datetime’2010-08-17T23%3A43%3A26.1913755Z’"
Server: Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: 4241109a-cd0b-4901-a8c5-c352d54f90c2
x-ms-version: 2009-09-19
Date: Tue, 17 Aug 2010 23:43:25 GMT
Content-Length: 1097

The returned entities, in this case a single entity, are returned in ATOM entry format in the response body:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<entry xml:base=http://myaccount.table.core.windows.net/ xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:etag="W/&quot;datetime’2010-08-17T23%3A43%3A26.1913755Z’&quot;" xmlns="http://www.w3.org/2005/Atom">
  <id>http://myaccount.table.core.windows.net/Novel(PartitionKey=’Beckett’,RowKey=’Molloy’)</id>
  <title type="text"></title>
  <updated>2010-08-17T23:43:26Z</updated>
  <author>
    <name />
  </author>
  <link rel="edit" title="Novel" href="Novel(PartitionKey=’Beckett’,RowKey=’Molloy’)" />
  <category term="myaccount.Novel" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
  <content type="application/xml">
    <m:properties>
      <d:PartitionKey>Beckett</d:PartitionKey>
      <d:RowKey>Molloy</d:RowKey>
      <d:Timestamp m:type="Edm.DateTime">2010-08-17T23:43:26.1913755Z</d:Timestamp>
      <d:Artist>Beckett</d:Artist>
      <d:Title>Molloy</d:Title>
    </m:properties>
  </content>
</entry>

Blob Service API 

The Blob Service API supports the following account-level operation:

The Blob Service API supports the following container-level operation:

The Blob Service API supports the following blob-level operation:

The Blob Service API supports the following operations on block blobs:

The Blob Service API supports the following operations on page blobs:

This section provides examples of the Put Blob and Lease Blob operations.

Put Blob

The Blob Service and Queue Service use a different form of shared-key authentication from the Table Service so care should be taken in creating the string to be signed for authorization. The blob type, BlockBlob or PageBlob, must be specified as a request header and consequently appears in the authorization string.

private void PutBlob(String containerName, String blobName)
{
    String requestMethod = "PUT";

    String urlPath = String.Format("{0}/{1}", containerName, blobName);

    String storageServiceVersion = "2009-09-19";

    String dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);

    String content = "The Name of This Band is Talking Heads";
    UTF8Encoding utf8Encoding = new UTF8Encoding();
    Byte[] blobContent = utf8Encoding.GetBytes(content);
    Int32 blobLength = blobContent.Length;

    const String blobType = "BlockBlob";

    String canonicalizedHeaders = String.Format(
          "x-ms-blob-type:{0}nx-ms-date:{1}nx-ms-version:{2}",
          blobType,
          dateInRfc1123Format,
          storageServiceVersion);
    String canonicalizedResource = String.Format("/{0}/{1}", AzureStorageConstants.Account, urlPath);
    String stringToSign = String.Format(
          "{0}nnn{1}nnnnnnnnn{2}n{3}
",
          requestMethod,
          blobLength,
          canonicalizedHeaders,
          canonicalizedResource);
    String authorizationHeader = CreateAuthorizationHeader(stringToSign);

    Uri uri = new Uri(AzureStorageConstants.BlobEndPoint + urlPath);
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    request.Method = requestMethod;
    request.Headers.Add("x-ms-blob-type", blobType);
    request.Headers.Add("x-ms-date", dateInRfc1123Format);
    request.Headers.Add("x-ms-version", storageServiceVersion);
    request.Headers.Add("Authorization", authorizationHeader);
    request.ContentLength = blobLength;

    using (Stream requestStream = request.GetRequestStream())
    {
        requestStream.Write(blobContent, 0, blobLength);
    }

    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        String ETag = response.Headers["ETag"];
    }
}

This generates the following request:

PUT http://myaccount.blob.core.windows.net/music/TalkingHeads HTTP/1.1
x-ms-blob-type: BlockBlob
x-ms-date: Tue, 17 Aug 2010 21:41:56 GMT
x-ms-version: 2009-09-19
Authorization: SharedKey myaccount:CGh+pI+kJamesBond007h6bze5pTUQ33uY9FI8yrPljY/ORU=
Host: myaccount.blob.core.windows.net
Content-Length: 38
Expect: 100-continue
Connection: Keep-Alive

The body of the request is:

The Name of This Band is Talking Heads

The Blob Service generates the following response:

HTTP/1.1 201 Created
Content-MD5: wZeVYaE0eQTH4gMN8OqDww==
Last-Modified: Tue, 17 Aug 2010 21:41:52 GMT
ETag: 0x8CD0C6C23EAD84B
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: 2e6dc56b-07e8-4164-90e0-e82eab326360
x-ms-version: 2009-09-19
Date: Tue, 17 Aug 2010 21:41:52 GMT
Content-Length: 0

Lease Blob

The Blob Service allows a user to lease a blob for a minute at a time and so acquire a write lock on it. The use case for this is the locking of a page blob used to store the VHD backing an writeable Azure Drive.

The LeaseBlob() example in this section demonstrates a subtle issue with the creation of authorization strings. The URL has a query string, comp=lease. Rather than using this directly in creating the authorization string it must be converted into comp:lease with a colon replacing the equal symbol – see modifiedURL in the example. Furthermore, the Lease Blob operation requires the use of an x-ms-lease-action to indicate whether the lease is being acquired, renewed, released or broken.

private void LeaseBlob(String containerName, String blobName)
{
    String requestMethod = "PUT";

    String urlPath = String.Format("{0}/{1}?comp=lease", containerName, blobName);
    String modifiedUrlPath = String.Format("{0}/{1}ncomp:lease", containerName, blobName);

    const Int32 contentLength = 0;

    String storageServiceVersion = "2009-09-19";
    String dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
    String leaseAction = “acquire”;
    String canonicalizedHeaders = String.Format(
           "x-ms-date:{0}nx-ms-lease-action:{1}nx-ms-version:{2}",
           dateInRfc1123Format,
           leaseAction ,
           storageServiceVersion );
    String canonicalizedResource = String.Format("/{0}/{1}", AzureStorageConstants.Account, modifiedUrlPath);
    String stringToSign = String.Format(
          "{0}nnn{1}nnnnnnnnn{2}n{3}",
          requestMethod,
          contentLength,
          canonicalizedHeaders,
          canonicalizedResource);
    String authorizationHeader = CreateAuthorizationHeader(stringToSign);

    Uri uri = new Uri(AzureStorageConstants.BlobEndPoint + urlPath);
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    request.Method = requestMethod;
    request.Headers.Add("x-ms-date", dateInRfc1123Format);
    request.Headers.Add("x-ms-lease-action", leaseAction );
    request.Headers.Add("x-ms-version", storageServiceVersion );
    request.Headers.Add("Authorization", authorizationHeader);
    request.ContentLength = contentLength;

    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        String leaseId = response.Headers["x-ms-lease-id"];
    }
}

This generates the following request:

PUT http://myaccount.blob.core.windows.net/music/TalkingHeads?comp=lease HTTP/1.1
x-ms-date: Tue, 17 Aug 2010 21:41:57 GMT
x-ms-lease-action: acquire
x-ms-version: 2009-09-19
Authorization: SharedKey myaccount:CGh+pI+kJamesBond007h6bze5pTUQ33uY9FI8yrPljY/ORU=
Host: myaccount.blob.core.windows.net
Content-Length: 0

The Blob Service generates the following response:

HTTP/1.1 201 Created
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: 04673cc1-884d-4868-bebe-ec729036e8ea
x-ms-version: 2009-09-19
x-ms-lease-id: f30650f7-2938-470f-a4d8-2636fb93cd9c
Date: Tue, 17 Aug 2010 21:41:52 GMT
Content-Length: 0

UPDATE 8/26/2010: Note there is a bug currently where after a blob is leased and its lease expires the blob is reported as being locked even though it is not.

Queue Service API

The Queue Service API supports the following queue-level operation:

The Queue Service API supports the following queue-level operation:

The Queue Service API supports the following message-level operations:

This section provides examples of the Put Message and Get Message operations.

Put Message

The most obvious curiosity about Put Message is that it uses the HTTP verb POST rather than PUT. The issue is presumably the interaction of the English language and the HTTP standard which states that PUT should be idempotent and that the Put Message operation is clearly not since each invocation merely adds another message to the queue. Regardless, it did catch me out when I failed to read the documentation well enough – so take that as a warning.

The content of a message posted to the queue must be formatted in a specified XML schema and must then be UTF8 encoded.

private void PutMessage(String queueName, String message)
{
    String requestMethod = "POST";

    String urlPath = String.Format("{0}/messages", queueName);

    String storageServiceVersion = "2009-09-19";
    String dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);

    String messageText = String.Format(
          "<QueueMessage><MessageText>{0}</MessageText></QueueMessage>", message);
    UTF8Encoding utf8Encoding = new UTF8Encoding();
    Byte[] messageContent = utf8Encoding.GetBytes(messageText);
    Int32 messageLength = messageContent.Length;

    String canonicalizedHeaders = String.Format(
          "x-ms-date:{0}nx-ms-version:{1}",
          dateInRfc1123Format,
          storageServiceVersion);
    String canonicalizedResource = String.Format("/{0}/{1}", AzureStorageConstants.Account, urlPath);
    String stringToSign = String.Format(
          "{0}nnn{1}nnnnnnnnn{2}n{3}",
          requestMethod,
          messageLength,
          canonicalizedHeaders,
          canonicalizedResource);
    String authorizationHeader = CreateAuthorizationHeader(stringToSign);

    Uri uri = new Uri(AzureStorageConstants.QueueEndPoint + urlPath);
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    request.Method = requestMethod;
    request.Headers.Add("x-ms-date", dateInRfc1123Format);
    request.Headers.Add("x-ms-version", storageServiceVersion);
    request.Headers.Add("Authorization", authorizationHeader);
    request.ContentLength = messageLength;

    using (Stream requestStream = request.GetRequestStream())
    {
        requestStream.Write(messageContent, 0, messageLength);
    }

    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        String requestId = response.Headers["x-ms-request-id"];
    }
}

This generates the following request:

POST http://myaccount.queue.core.windows.net/tasks/messages HTTP/1.1
x-ms-date: Tue, 17 Aug 2010 21:41:58 GMT
x-ms-version: 2009-09-19
Authorization: SharedKey myaccount:CGh+pI+kJamesBond007h6bze5pTUQ33uY9FI8yrPljY/ORU=
Host: myaccount.queue.core.windows.net
Content-Length: 70
Expect: 100-continue

The body of the request is:

<QueueMessage><MessageText>Do the laundry</MessageText></QueueMessage>

The Queue Service generates the following response:

HTTP/1.1 201 Created
Server: Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: ccaebe11-6701-4270-b878-c7226c457331
x-ms-version: 2009-09-19
Date: Tue, 17 Aug 2010 21:41:54 GMT
Content-Length: 0

Get Messages

The Get Messages operation described in this section retrieves a single message with the default message visibility timeout of 30 seconds.

private void GetMessage(String queueName)
{
    string requestMethod = "GET";

    String urlPath = String.Format("{0}/messages", queueName);

    String storageServiceVersion = "2009-09-19";
    String dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
    String canonicalizedHeaders = String.Format(
          "x-ms-date:{0}nx-ms-version:{1}",
          dateInRfc1123Format,
          storageServiceVersion );
    String canonicalizedResource = String.Format("/{0}/{1}", AzureStorageConstants.Account, urlPath);
    String stringToSign = String.Format(
          "{0}nnnnnnnnnnnn{1}n{2}",
          requestMethod,
          canonicalizedHeaders,
          canonicalizedResource);
    String authorizationHeader = CreateAuthorizationHeader(stringToSign);

    Uri uri = new Uri(AzureStorageConstants.QueueEndPoint + urlPath);
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    request.Method = requestMethod;
    request.Headers.Add("x-ms-date", dateInRfc1123Format);
    request.Headers.Add("x-ms-version", storageServiceVersion );
    request.Headers.Add("Authorization", authorizationHeader);
    request.Accept = "application/atom+xml,application/xml";

    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        Stream dataStream = response.GetResponseStream();
        using (StreamReader reader = new StreamReader(dataStream))
        {
            String responseFromServer = reader.ReadToEnd();
        }
    }
}

This generates the following request:

GET http://myaccount.queue.core.windows.net/tasks/messages HTTP/1.1
x-ms-date: Tue, 17 Aug 2010 21:41:58 GMT
x-ms-version: 2009-09-19
Authorization: SharedKey myaccount:CGh+pI+kJamesBond007h6bze5pTUQ33uY9FI8yrPljY/ORU=
Accept: application/atom+xml,application/xml
Host: myaccount.queue.core.windows.net

The Queue Service generates the following response:

HTTP/1.1 200 OK
Content-Type: application/xml
Server: Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: a364fb8b-bec0-4fa9-859a-0e2c4c65dbb9
x-ms-version: 2009-09-19
Date: Tue, 17 Aug 2010 21:41:54 GMT
Content-Length: 468

The message is returned in the response body as follows:

<?xml version="1.0" encoding="utf-8"?><QueueMessagesList><QueueMessage><MessageId>dfc36ee6-41f8-4428-9723-1a6da921daa3</MessageId><InsertionTime>Tue, 17 Aug 2010 19:41:13 GMT</InsertionTime><ExpirationTime>Tue, 24 Aug 2010 19:41:13 GMT</ExpirationTime><DequeueCount>2</DequeueCount><PopReceipt>AgAAAAEAAADbCwAAKiBFFFU+ywE=</PopReceipt><TimeNextVisible>Tue, 17 Aug 2010 21:42:24 GMT</TimeNextVisible><MessageText>b25l</MessageText></QueueMessage></QueueMessagesList>

-Blog

Copyright© fullvirtue.com プロダクトオーナー支援スペシャリストのBlog , 2024 All Rights Reserved.