【IT168微软云计算博客征文专稿】本文介绍如何创建、查询和删除Blob数据,所使用的数据来自Queue的消息数据。
首先在 Default.aspx 中增加Blob相关的成员变量:
private static BlobStorage _blobStorage = null;
private static BlobContainer _blobContainer = null;
const int UPDATE_TIMEOUT_SEC = 5;
const string SUFFIX = "xml";
然后再给 _Initialization 处理程序增加初始化代码:
{
if (_initialized)
{
return;
}
lock (_syncObj)
{
try
{
_blobStorage =
BlobStorage.Create(StorageAccountInfo
.GetDefaultBlobStorageAccountFromConfiguration());
_blobContainer = _blobStorage.GetBlobContainer(BLOB_CONTAINER_NAME);
// 让容器公开,以便我们可以使用REST API从Web通过URI查询Blob
_blobContainer.CreateContainer(new NameValueCollection(),
ContainerAccessControl.Public);
_queueStorage =
QueueStorage.Create(StorageAccountInfo
.GetDefaultQueueStorageAccountFromConfiguration());
_queueStorage.RetryPolicy =
RetryPolicies.RetryN(3, TimeSpan.FromSeconds(5));
MessageQueue queue = _queueStorage.GetQueue(BLOB_PAYLOAD_QUEUE_NAME);
queue.CreateQueue();
queue.MessageReceived +=
new MessageReceivedEventHandler(_OnMessageReceive);
queue.PollInterval = 500; // 单位毫秒
queue.StartReceiving(); // 开始投票
}
catch (WebException ex)
{
throw new WebException(
string.Format(
"---{0}:_Initialization, Windows Azure failed to instatiate storage
using current account information. Exception caught : {1}",
this.ToString(),
ex.Message
)
);
}
_initialized = true;
}
}
ContainerAccessControl 应该被设置为 Public ,以便应用程序可以使用REST API查询Blob数据,为了改变访问范围,这里提供了两个 CreateContainer() 方法,第一个通过传递一个Blob容器名实例化Blob容器对象,第二个仅仅是调用Blob容器类的一个函数,它必须通过传递一个枚举值 ContainerAccessControl.Public 使用有效的Blob容器实例,这个调用不是必需的,不会覆盖实例本身,但可以修改访问范围。
调用 _Initialization() 后,Blob存储和Blob容器都已实例化,可以使用Blob容器实例创建一个Blob记录,如:
{
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);
// 创建与Blob关联的元数据
NameValueCollection metadata = new NameValueCollection();
metadata["MediaID"] = message.Id;
properties.Metadata = metadata;
properties.ContentType = "text/xml";
// 创建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();
}
在这个例子中,Blob存储的名字是在接收到Queue消息时创建的,而Blob名是Blob创建时指定的,Blob名可以是任意的,但最好不要包括账号名,因为账号名在部署到Azure云时是可以通过配置文件修改的。
Azure提供了一个名叫服务总线的服务,为了让Blob存储适应.NET服务总线,建议构思Blob名时多花点心思,下面就是我的一些心得体会:
· 使用.NET命名空间约定构思Blob名
· 基于Blob的逻辑或关系结构以分层思想构思Blob名
当 BlobProperties 对象实例化后,Azure Blob存储的元数据就构造好了,元数据对象是嵌入在 BlobProperties. 的对象实例中的,元数据是Blob存储的属性集,元数据是名称/值对的格式,元数据的真实类叫做 NameValueCollection, ,在这个类实例化之前,命名空间 System.Collections.Specialized 必须包括进来。
Blob容器在创建Blob存储时会用到两个参数: BlobContents 和 BlobProperties. 。第一个参数容纳了信息的主体,第二个参数容纳了信息的属性,只有 Strea m(流)和 Byte array (字节数组)数据类型可以用于这两个参数,信息主体在实例化成 BlobContents 对象之前,必须转换成这两个数据类型。我们在消息队列事件处理程序中创建Blob对象:
图1显示了运行时的 Default.aspx 页面。

图 1 Blob创建结果页面
图2显示了在 SQL Server Management Studio 中,从 DevelopmentStorageDb 查询 Accounts , AcctBlobContainerMap , BlobContainer 和Blob表的结果。
图 2 Blob存储记录创建后的查询结果