- Two approaches to create storage client via Azure Client Library
- via connection string
- via base URI and storage credential
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
namespace AzureTest
{
class Program
{
static void Main(string[] args)
{
//Approach 1 : use connectionstring
CloudStorageAccount account = CloudStorageAccount.
Parse(System.Configuration.ConfigurationManager.AppSettings["StorageAccountConnectionString"]);
//Approach 2 : Use base uri + StorageCredentialsAccountAndKey
string accountName = System.Configuration.ConfigurationManager.AppSettings["accountName"];
string key = System.Configuration.ConfigurationManager.AppSettings["accountKey"];
StorageCredentialsAccountAndKey credentials = new StorageCredentialsAccountAndKey(accountName, key);
string baseUri = string.Format("http://127.0.0.1:10002/{0}", accountName);
CloudBlobClient BlobClient = account.CreateCloudBlobClient();
CloudTableClient tableClient = new CloudTableClient(baseUri, credentials);
}
}
}
- Upload File using Blob and Parallel Blob Upload using Block Blob
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
using System.Threading.Tasks;
using System.IO;
namespace AzureTest
{
class Program
{
static void Main(string[] args)
{
CloudStorageAccount account = CloudStorageAccount.
Parse(System.Configuration.ConfigurationManager.AppSettings["StorageAccountConnectionString"]);
//Blob: Upload File
CloudBlobClient BlobClient = account.CreateCloudBlobClient();
CloudBlobContainer ContainerReference = BlobClient.GetContainerReference("practicecontainer");
ContainerReference.CreateIfNotExist();
CloudBlob BlobReference = ContainerReference.GetBlobReference("blobfile.doc");
BlobReference.UploadFile("blobfile.doc");
byte[] DownloadAsByteArray = BlobReference.DownloadByteArray();
Console.WriteLine(DownloadAsByteArray);
Console.ReadKey();
//Block Blob : Parallel Blob Uploads
var blockBlob = BlobReference.ToBlockBlob;
var blockLength = 100 * 1024;//each block 100KB
var dataToUpload = File.ReadAllBytes("blobfile.doc");
var numberOfBlocks = ((int) dataToUpload.Length / blockLength) + 1;
string[] blockIds = new string[numberOfBlocks];
Parallel.For(0, numberOfBlocks, x =>
{
var blockId = Convert.ToBase64String(Guid.NewGuid().ToByteArray());
var currentLength = Math.Min(blockLength, dataToUpload.Length - (x * blockLength));
using (var memStream = new MemoryStream(dataToUpload, x * blockLength, currentLength))
{
blockBlob.PutBlock(blockId, memStream, null);
}
blockIds[x] = blockId;
});
blockBlob.PutBlockList(blockIds);
DownloadAsByteArray = BlobReference.DownloadByteArray();
Console.WriteLine(DownloadAsByteArray);
Console.ReadKey();
}
}
}
- Copy Blob and Snapshot Blob + use Snapshot blob to restore current blob
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
using System.Threading.Tasks;
using System.IO;
namespace AzureTest
{
class Program
{
static void Main(string[] args)
{
CloudStorageAccount account = CloudStorageAccount.
Parse(System.Configuration.ConfigurationManager.AppSettings["StorageAccountConnectionString"]);
CloudBlobClient BlobClient = account.CreateCloudBlobClient();
CloudBlobContainer ContainerReference = BlobClient.GetContainerReference("practicecontainer");
ContainerReference.CreateIfNotExist();
BlobContainerPermissions permissions = new BlobContainerPermissions();
permissions.PublicAccess = BlobContainerPublicAccessType.Container;
ContainerReference.SetPermissions(permissions);
CloudBlob BlobReference = ContainerReference.GetBlobReference("blobfile.doc");
//Copy Blob
BlobRequestOptions options = new BlobRequestOptions()
{
Timeout = TimeSpan.FromSeconds(45),
RetryPolicy = RetryPolicies.RetryExponential(
RetryPolicies.DefaultClientRetryCount, RetryPolicies.DefaultClientBackoff)
};
CloudBlob destinationBlob = ContainerReference.GetBlobReference("Copy/blobfile copy.doc");
destinationBlob.CopyFromBlob(BlobReference, options);
//Snapshot Blob
BlobReference.CreateSnapshot();
//Replace Blob With New Version
BlobReference.UploadFile("blobfilev2.doc");
//Get the Snapshot
var snapshots = ContainerReference.ListBlobs(new BlobRequestOptions()
{ BlobListingDetails = BlobListingDetails.Snapshots,
UseFlatBlobListing = true
});
BlobReference.FetchAttributes();
Console.WriteLine(BlobReference.Attributes.Properties.Length);
foreach (CloudBlob c in snapshots.Where(item => ((CloudBlob)item).SnapshotTime.HasValue && item.Uri.Equals(BlobReference.Uri)))
{
BlobReference.CopyFromBlob(c);
break;
}
BlobReference.FetchAttributes();
Console.WriteLine(BlobReference.Attributes.Properties.Length);
Console.ReadKey();
}
}
}
- Lease Blob
using System;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
using Microsoft.WindowsAzure.StorageClient.Protocol;
using System.IO;
namespace AzureStorageTest
{
class Program
{
static void Main(string[] args)
{
CloudStorageAccount account = CloudStorageAccount.
Parse(System.Configuration.ConfigurationManager.AppSettings["StorageAccountConnectionString"]);
CloudBlobClient BlobClient = account.CreateCloudBlobClient();
CloudBlobContainer ContainerReference = BlobClient.GetContainerReference("maincontainer");
ContainerReference.CreateIfNotExist();
CloudBlob BlobReference = ContainerReference.GetBlobReference("blobfile.txt");
var leaseId = BlobReference.AcquireLease();
// BlobReference.UploadText("new content", "123");
BlobReference.UploadText("new content", leaseId);
byte[] DownloadAsByteArray = BlobReference.DownloadByteArray();
Console.WriteLine(DownloadAsByteArray);
Console.ReadKey();
}
}
public static class LeaseBlobExtensions
{
public static string AcquireLease(this CloudBlob blob)
{
var creds = blob.ServiceClient.Credentials;
var transformedUri = new Uri(creds.TransformUri(blob.Uri.ToString()));
var req = BlobRequest.Lease(transformedUri,
90, // timeout (in seconds)
LeaseAction.Acquire, // as opposed to "break" "release" or "renew"
null); // name of the existing lease, if any
blob.ServiceClient.Credentials.SignRequest(req);
using (var response = req.GetResponse())
{
return response.Headers["x-ms-lease-id"];
}
}
public static void UploadText(this CloudBlob blob, string text, string leaseId)
{
string url = blob.Uri.ToString();
if (blob.ServiceClient.Credentials.NeedsTransformUri)
{
url = blob.ServiceClient.Credentials.TransformUri(url);
}
var req = BlobRequest.Put(new Uri(url), 90, new BlobProperties(), BlobType.BlockBlob, leaseId, 0);
using (var writer = new StreamWriter(req.GetRequestStream()))
{
writer.Write(text);
}
blob.ServiceClient.Credentials.SignRequest(req);
req.GetResponse().Close();
}
}
}
- Meta Data and Share Access Policy & Share Access Signatures
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
using System.Threading.Tasks;
using System.IO;
using System.Collections.Specialized;
namespace AzureTest
{
class Program
{
static void Main(string[] args)
{
CloudStorageAccount account = CloudStorageAccount.
Parse(System.Configuration.ConfigurationManager.AppSettings["StorageAccountConnectionString"]);
CloudBlobClient BlobClient = account.CreateCloudBlobClient();
CloudBlobContainer ContainerReference = BlobClient.GetContainerReference("practicecontainer");
ContainerReference.CreateIfNotExist();
//BlobContainerPermissions permissions = new BlobContainerPermissions();
//permissions.PublicAccess = BlobContainerPublicAccessType.Container;
//ContainerReference.SetPermissions(permissions);
CloudBlob BlobReference = ContainerReference.GetBlobReference("blobfile.doc");
var metadata = new NameValueCollection();
metadata["Id"] = "1";
metadata["Filename"] = "doc file";
metadata["ImageName"] = String.IsNullOrEmpty("blobfile.doc") ? "unknown" : "blobfile.doc";
metadata["Description"] = String.IsNullOrEmpty("description") ? "unknown" : "description";
metadata["Tags"] = String.IsNullOrEmpty("") ? "unknown" : "";
// Add and commit metadata to blob
BlobReference.Metadata.Add(metadata);
//CloudBlobContainer.FetchAttributes Method:
//Retrieves the container's attributes, including its system properties and user-defined metadata.
//CloudBlobContainer container = BlobClient.GetContainerReference(containerName);
//container.FetchAttributes();
//Get Meta data
var items = BlobReference.Metadata.AllKeys.SelectMany(BlobReference.Metadata.GetValues,(k, v) => new {key = k, value = v});
foreach (var item in items)
{
Console.WriteLine(String.Format("Name :{0}, Value:{1}",item.key, item.value));
}
//OR
foreach (string key in BlobReference.Metadata.Keys)
{
Console.WriteLine(String.Format("Name :{0}, Value:{1}", key, BlobReference.Metadata[key]));
}
//ACL(Access Control List) - Container Level
BlobContainerPermissions permission = new BlobContainerPermissions();
/*
* Full public read access: Container and blob data can be read via anonymous request.
* Clients can enumerate blobs within the container via anonymous
* request, but cannot enumerate containers within the storage account.
Public read access for blobs only: Blob data within this container can be
* read via anonymous request, but container data is not available.
* Clients cannot enumerate blobs within the container
* via anonymous request.
No public read access: Container and blob data can be read by the account owner only.
* */
permission.PublicAccess = BlobContainerPublicAccessType.Off;
ContainerReference.SetPermissions(permission);
//Share Access policy - Container Level
SortedList<string, SharedAccessPolicy> policies = new SortedList<string, SharedAccessPolicy>();
permission.SharedAccessPolicies.Clear();
SharedAccessPolicy policy1 = new SharedAccessPolicy()
{
Permissions = SharedAccessPermissions.List | SharedAccessPermissions.Read | SharedAccessPermissions.Write | SharedAccessPermissions.Delete,
SharedAccessStartTime = DateTime.UtcNow,
SharedAccessExpiryTime = DateTime.UtcNow.AddHours(1)
};
policies.Add("Policy1", policy1);
policies.Add("Policy2", new SharedAccessPolicy()
{
Permissions = SharedAccessPermissions.Read,
SharedAccessStartTime = DateTime.Parse("2010-01-01T09:38:05Z"),
SharedAccessExpiryTime = DateTime.Parse("2012-12-31T09:38:05Z")
});
if (policies != null)
{
foreach (KeyValuePair<string, SharedAccessPolicy> policy in policies)
{
permission.SharedAccessPolicies.Add(policy.Key, policy.Value);
}
}
ContainerReference.SetPermissions(permission);
//GenerateSharedAccessSignature via policy
string signature = ContainerReference.GetSharedAccessSignature(policy1);
Console.WriteLine("Container Shared Access Signature via policy: " + signature);
//GenerateSharedAccessSignature via policy string
signature = ContainerReference.GetSharedAccessSignature(new SharedAccessPolicy(), "Policy1");
Console.WriteLine("Container Shared Access Signature via policy name: " + signature);
//Share Access Signature - Blob Level
permission.PublicAccess = BlobContainerPublicAccessType.Off;
permission.SharedAccessPolicies.Clear();
ContainerReference.SetPermissions(permission);
var sas = BlobReference.GetSharedAccessSignature(new SharedAccessPolicy()
{
Permissions = SharedAccessPermissions.Read
|SharedAccessPermissions.Write,
SharedAccessExpiryTime = DateTime.UtcNow + TimeSpan.FromMinutes(5)
});
Console.WriteLine("This link should work for the next five minutes:");
Console.WriteLine(BlobReference.Uri.AbsoluteUri + sas);
Console.ReadKey();
}
}
}
- Tables Operations
- set IgnoreResourceNotFoundException
- insert entity
- ReplaceUpdateEntity + Entity GroupTransactions
- Merge update
- Upsert - InsertOrReplace
- Upsert - InsertOrMerge
- Delete Entity
- Show Result
- Delete Table
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Services.Common;
namespace AzureTest
{
[DataServiceKey("PartitionKey", "RowKey")]
public class Movie
{
public string PartitionKey { get; set; }
public string RowKey { get; set; }
public DateTime Timestamp { get; set; }
public double Rating { get; set; }
public bool Favorite { get; set; }
public Movie() { }
public Movie(string partitionKey, string rowKey)
{
PartitionKey = partitionKey;
RowKey = rowKey;
Rating = 5;
Favorite = false;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
using System.Threading.Tasks;
using System.IO;
using System.Collections.Specialized;
using System.Data.Services.Client;
namespace AzureTest
{
class Program
{
static void Main(string[] args)
{
CloudStorageAccount account = CloudStorageAccount.
Parse(System.Configuration.ConfigurationManager.AppSettings["StorageAccountConnectionString"]);
CloudTableClient tableClient = account.CreateCloudTableClient();
tableClient.RetryPolicy = RetryPolicies.Retry(4, TimeSpan.Zero);
string tableName = "Movies";
tableClient.CreateTableIfNotExist(tableName);
TableServiceContext context = tableClient.GetDataServiceContext();
//IgnoreResourceNotFoundException
//Issue: FirstOrDefault() return 404 error
//You have to set IgnoreResourceNotFoundException = true in the TableServiceContext in order
//to receive null when an entity is not found instead of error 404
context.IgnoreMissingProperties = true;
// Insert movie
context.AddObject(tableName, new Movie("Action", "1White Water Rapids Survival"));
context.AddObject(tableName, new Movie("Action", "2White Water Rapids Survival"));
context.AddObject(tableName, new Movie("Action", "3White Water Rapids Survival"));
context.AddObject(tableName, new Movie("Action", "4White Water Rapids Survival"));
context.AddObject(tableName, new Movie("Action", "5White Water Rapids Survival"));
context.AddObject(tableName, new Movie("Comedy", "6White Water Rapids Survival"));
context.AddObject(tableName, new Movie("Comedy", "7White Water Rapids Survival"));
context.SaveChangesWithRetries();
// ReplaceUpdateEntity + Entity GroupTransactions
context = tableClient.GetDataServiceContext();
var q1 = (from movie in context.CreateQuery<Movie>(tableName)
where movie.PartitionKey == "Action" && movie.Rating > 4.0
select movie).AsTableServiceQuery<Movie>();
foreach (Movie movieToUpdate in q1)
{
movieToUpdate.Favorite = true;
context.UpdateObject(movieToUpdate);
}
context.SaveChangesWithRetries(SaveChangesOptions.Batch | SaveChangesOptions.ReplaceOnUpdate);
// Merge update
context = tableClient.GetDataServiceContext();
var q2 = (from movie in context.CreateQuery<Movie>(tableName)
where movie.PartitionKey == "Action" && movie.Rating > 4.0
select movie).AsTableServiceQuery<Movie>();
foreach (Movie movieToUpdate in q2)
{
movieToUpdate.Favorite = false;
context.UpdateObject(movieToUpdate);
}
context.SaveChangesWithRetries(SaveChangesOptions.Batch);
// Upsert - InsertOrReplace (Note that insert-or-replace is not supported on the local storage emulator)
//TableServiceContext serviceContext = tableClient.GetDataServiceContext();
//// Create a new customer entity
//Movie newmovie = new Movie("Action", "9White Water Rapids Survival");
//newmovie.Rating = 6;
//serviceContext.AttachTo(tableName, newmovie);
//serviceContext.UpdateObject(newmovie);
//serviceContext.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate);
//// Upsert - InsertOrMerge (Note that insert-or-replace is not supported on the local storage emulator)
//serviceContext = tableClient.GetDataServiceContext();
//// Create a new customer entity
//Movie newmovie2 = new Movie("Action", "9White Water Rapids Survival");
//newmovie2.Rating = 7;
//serviceContext.AttachTo(tableName, newmovie2);
//serviceContext.UpdateObject(newmovie2);
//serviceContext.SaveChangesWithRetries();
//Delete Entity
context = tableClient.GetDataServiceContext();
var entity = (from movie in context.CreateQuery<Movie>(tableName)
select movie).FirstOrDefault<Movie>();
context.DeleteObject(entity);
context.SaveChangesWithRetries();
//Show Result
var result = (from movie in context.CreateQuery<Movie>(tableName)
select movie).FirstOrDefault<Movie>();
Console.WriteLine(String.Format(
"result.PartitionKey:{0}\n result.RowKey:{1} \n result.Timestamp:{2} \n result.Rating:{3} \n result.Favorite:{4}",
result.PartitionKey,
result.RowKey,
result.Timestamp,
result.Rating,
result.Favorite));
//Delete Table
tableClient.DeleteTableIfExist(tableName);
Console.ReadKey();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
using System.Threading.Tasks;
using System.IO;
using System.Collections.Specialized;
using System.Data.Services.Client;
using System.Threading;
namespace AzureTest
{
class Program
{
static void Main(string[] args)
{
CloudStorageAccount account = CloudStorageAccount.
Parse(System.Configuration.ConfigurationManager.AppSettings["StorageAccountConnectionString"]);
CloudQueueClient queueStorage = account.CreateCloudQueueClient();
queueStorage.RetryPolicy = RetryPolicies
.RetryExponential(RetryPolicies.DefaultClientRetryCount,
RetryPolicies.DefaultMaxBackoff);
//Create Queue
CloudQueue queue = queueStorage.GetQueueReference("guestthumbs");
queue.CreateIfNotExist();
//Insert a Message into a Queue
for (int i = 0; i < 20; i++)
{
var message = new CloudQueueMessage(String.Format("{0},{1},{2}",
i + ":uniqueBlobName",
"entry.PartitionKey",
"entry.RowKey"));
queue.AddMessage(message);
Console.WriteLine("Input Message :" + message);
}
//Change the Contents of a Queued Message
CloudQueueMessage updatemessage = queue.GetMessage();
updatemessage.SetMessageContent("Updated contents.");
queue.UpdateMessage(updatemessage,
TimeSpan.FromSeconds(0.0), // visible immediately
MessageUpdateFields.Content | MessageUpdateFields.Visibility);
//Allow applications to schedule work to be processed at a later time
//Processing applications can update the message content of a message they have dequeued to save progress
//state so that a new worker can continue from that state if the prior worker crashed
queue.PutMessage(account.Credentials,
EncodeMessage("new feature message", ProcessingState.VirusScan),
24 * 60 * 60, // StartVisibilityTimeout : set to 1 day,<int=seconds>
24 * 60 * 60 * 3, //MessageTtl set to 3 days,<int-seconds>
60);//ServerRequestTimeout
//Processing applications can now extend the visibility timeout on a message they have dequeued
CloudQueueMessage extendmessage = queue.GetMessage();
string newPopReceipt = "";
DateTime nextVisibilityTime=DateTime.UtcNow;
queue.UpdateMessage(account.Credentials,
extendmessage.Id,
extendmessage.PopReceipt,
24 * 60 * 60,//From now extend 1 days
extendmessage.AsString,
60,//ServerRequestTimeout
out newPopReceipt,
out nextVisibilityTime);
//Dequeue the Next Message
IEnumerable<CloudQueueMessage> msgList = queue.GetMessages(32, TimeSpan.FromSeconds(20));
if (msgList == null)
{
//Time Sleep
Thread.Sleep(TimeSpan.FromSeconds(5));
}
else
{
try
{
foreach (CloudQueueMessage msg in msgList)
{
if (msg.DequeueCount < 8)
{
Console.WriteLine("Output Message : " + msg.AsString);
}
else
{
//Handle Poison Message
}
queue.DeleteMessage(msg);
}
}
catch (StorageClientException ex)
{
if (ex.ExtendedErrorInformation.ErrorCode == "MessageNotFound")
{
// pop receipt must be invalid
// ignore or log (so we can tune the visibility timeout)
}
else
{
// not the error we were expecting
throw;
}
}
}
//Get the Queue Length
int freshMessageCount = queue.RetrieveApproximateMessageCount();
int? cachedMessageCount = queue.ApproximateMessageCount;
Console.WriteLine(String.Format("freshMessageCount:{0} /n cachedMessageCount:{1}"
, freshMessageCount
, cachedMessageCount.Value));
//Delete a Queue
queue.Delete();
Console.ReadKey();
}
/// <summary>
/// The processing stages for a message
/// </summary>
public enum ProcessingState : int
{
VirusScan = 1,
Encoder = 2,
Compress = 3,
Completed = 4
}
/// <summary>
/// Form of the queue message is: [2 digits for state][Actual Message content]
/// </summary>
/// <param name="content"></param>
/// <param name="state"></param>
/// <returns></returns>
private static string EncodeMessage(string content, ProcessingState state)
{
return string.Format("{0:D2}{1}", (int)state, content);
}
}
}
Class QueueExtensions
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using Microsoft.WindowsAzure.StorageClient.Protocol;
using System.IO;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
// NOTE: Please test these before using in production
public static class QueueExtensions
{
/// <summary>
/// Add a message to the queue. The visibility timeout param can be used to optionally
/// make the message visible at a future time
/// </summary>
/// <param name="queue">
/// The queue to add message to
/// </param>
/// <param name="credentials">
/// The storage credentials used for signing
/// </param>
/// <param name="message">
/// The message content
/// </param>
/// <param name="visibilityTimeout">
/// value in seconds and should be greater than or equal to 0 and less than 604800 (7 days).
/// It should also be less than messageTimeToLive
/// </param>
/// <param name="messageTimeToLive">
/// (Optional) Time after which the message expires if it is not deleted from the queue.
/// It can be a maximum time of 7 days.
/// </param>
/// <param name="timeout">
/// Server timeout value
/// </param>
public static void PutMessage(
this CloudQueue queue,
StorageCredentials credentials,
string message,
int? visibilityTimeout,
int? messageTimeToLive,
int timeout)
{
StringBuilder builder = new StringBuilder(queue.Uri.AbsoluteUri);
builder.AppendFormat("/messages?timeout={0}", timeout);
if (messageTimeToLive != null)
{
builder.AppendFormat("&messagettl={0}", messageTimeToLive.ToString());
}
if (visibilityTimeout != null)
{
builder.AppendFormat("&visibilitytimeout={0}", visibilityTimeout);
}
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(builder.ToString());
request.Method = "POST";
request.Headers.Add("x-ms-version", "2011-08-18");
byte[] buffer = QueueRequest.GenerateMessageRequestBody(message);
request.ContentLength = buffer.Length;
credentials.SignRequest(request);
using (Stream stream = request.GetRequestStream())
{
stream.Write(buffer, 0, buffer.Length);
}
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
// we expect 201 for Put Message
if (response.StatusCode != HttpStatusCode.Created)
{
throw new InvalidOperationException("Unexpected response code.");
}
}
}
catch (WebException e)
{
// Log any exceptions for debugging
LogWebException(e);
throw;
}
}
/// <summary>
/// Update the message to extend visibility timeout and optionally
/// the message contents
/// </summary>
/// <param name="queue">
/// The queue to operate on
/// </param>
/// <param name="credentials">
/// The storage credentials used for signing
/// </param>
/// <param name="messageId">
/// The ID of message to extend the lease on
/// </param>
/// <param name="popReceipt">
/// pop receipt to use
/// </param>
/// <param name="visibilityTimeout">
/// Value should be greater than or equal to 0 and less than 7.
/// </param>
/// <param name="messageBody">
/// (optional) The message content
/// </param>
/// <param name="timeout">
/// Server timeout value
/// </param>
/// <param name="newPopReceiptID">
/// Return the new pop receipt that should be used for subsequent requests when
/// the lease is held
/// </param>
/// <param name="nextVisibilityTime">
/// Return the next visibility time for the message. This is time until which the lease is held
/// </param>
public static void UpdateMessage(
this CloudQueue queue,
StorageCredentials credentials,
string messageId,
string popReceipt,
int visibilityTimeout,
string messageBody,
int timeout,
out string newPopReceiptID,
out DateTime nextVisibilityTime)
{
StringBuilder builder = new StringBuilder(queue.Uri.AbsoluteUri);
builder.AppendFormat(
"/messages/{0}?timeout={1}&popreceipt={2}&visibilitytimeout={3}",
messageId,
timeout,
Uri.EscapeDataString(popReceipt),
visibilityTimeout);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(builder.ToString());
request.Method = "PUT";
request.Headers.Add("x-ms-version", "2011-08-18");
if (messageBody != null)
{
byte[] buffer = QueueRequest.GenerateMessageRequestBody(messageBody);
request.ContentLength = buffer.Length;
credentials.SignRequest(request);
using (Stream stream = request.GetRequestStream())
{
stream.Write(buffer, 0, buffer.Length);
}
}
else
{
request.ContentLength = 0;
credentials.SignRequest(request);
}
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
if (response.StatusCode != HttpStatusCode.NoContent)
{
throw new InvalidOperationException("Unexpected response code.");
}
newPopReceiptID = response.Headers["x-ms-popreceipt"];
nextVisibilityTime = DateTime.Parse(response.Headers["x-ms-time-next-visible"]);
}
}
catch (WebException e)
{
// Log any exceptions for debugging
LogWebException(e);
throw;
}
}
/// <summary>
/// Get messages has been provided only because storage client library does not allow
/// invisibility timeout to exceed 2 hours
/// </summary>
/// <param name="queue">
/// The queue to operate on
/// </param>
/// <param name="credentials">
/// The storage credentials used for signing
/// </param>
/// <param name="messageId">
/// The ID of message to extend the lease on
/// </param>
/// <param name="popReceipt">
/// pop receipt to use
/// </param>
/// <param name="visibilityTimeout">
/// Value should be greater than or equal to 0 and less than 7.
/// </param>
/// <param name="messageBody">
/// (optional) The message content
/// </param>
/// <param name="timeout">
/// Server timeout value
/// </param>
/// <param name="newPopReceiptID">
/// Return the new pop receipt that should be used for subsequent requests when
/// the lease is held
/// </param>
/// <param name="nextVisibilityTime">
/// Return the next visibility time for the message. This is time until which the lease is held
/// </param>
public static IEnumerable<QueueMessage> GetMessages(
this CloudQueue queue,
StorageCredentials credentials,
int? visibilityTimeout,
int? messageCount,
int timeout)
{
StringBuilder builder = new StringBuilder(queue.Uri.AbsoluteUri);
builder.AppendFormat(
"/messages?timeout={0}",
timeout);
if (messageCount != null)
{
builder.AppendFormat("&numofmessages={0}", messageCount);
}
if (visibilityTimeout != null)
{
builder.AppendFormat("&visibilitytimeout={0}", visibilityTimeout);
}
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(builder.ToString());
request.Method = "GET";
request.Headers.Add("x-ms-version", "2011-08-18");
credentials.SignRequest(request);
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
if (response.StatusCode != HttpStatusCode.OK)
{
throw new InvalidOperationException("Unexpected response code.");
}
GetMessagesResponse msgResponses = QueueResponse.GetMessages(response);
// force it to be parsed right away else the response will be closed
// since QueueResponse.GetMessages parses responses lazily.
QueueMessage[] messages = msgResponses.Messages.ToArray<QueueMessage>();
return messages.AsEnumerable<QueueMessage>();
}
}
catch (WebException e)
{
// Log any exceptions for debugging
LogWebException(e);
throw;
}
}
/// <summary>
/// Log the exception in your preferred logging system
/// </summary>
/// <param name="e">
/// The exception to log
/// </param>
private static void LogWebException(WebException e)
{
HttpWebResponse response = e.Response as HttpWebResponse;
Console.WriteLine(string.Format(
"Request failed with '{0}'. Status={1} RequestId={2} Exception={3}",
e.Message,
response.StatusCode,
response != null ? response.Headers["x-ms-request-id"] : "<NULL>",
e.ToString()));
// Log to your favorite location…
}
}