摘要:无责任Windows Azure SDK .NET开发入门篇,将带来一系列基础文章:从Windows Azure开发前准备工作、使用Azure AD 管理用户信息、创建管理“云”服务、到使用Blob Storage服务等,帮助读者轻易上手使用这套开发工具。
完成了身份授权和用户信息管理,我们终于可以真正使用Azure的服务了。Azure PaaS服务中比较出名的首推存储服务,存储服务中比较出名的首推Blob Storage服务,本章我们使用SDK 完成Blob Storage服务的应用。
Blob 存储一般用于存储文件数据。Blob 可以是任何类型的文本或二进制数据,如文档、媒体文件或应用程序安装程序。也就是说Blog非常适合用于存储提供下载的文件。在开封Blob服务前,你需要了解几个概念
- 帐户。存储帐户是存储系统中的一个全局唯一标识的实体。帐户是 BLOB 服务的父级命名空间。所有容器都与一个帐户关联。
-
容器。容器是帐户内一组用户定义的 Blob。容器资源没有关联的内容,只有属性和元数据。容器名称必须是有效的 DNS 名称且符合以下命名规则
-
Blob。Blob 是表示一组内容的实体。Blob 资源包含内容、属性和元数据。Blob 名称可以包含任何字符组合,长度必须至少为 1 个字符,且不能超过 1,024 个字符。Blob 名称区分大小写,且组成 Blob 名称的路径段数目不能超过 254 个。大部分文件是块 blobs。单个块 blob 最大可以为 200 GB。
-
URL 格式: Blob 可使用以下 URL 格式寻址:http://<storage account>.blob.core.chinacloudapi.cn/<container>/<blob>
你一定要记住:BLOB 服务基于平面存储方案而不是分层方案。但是,可以在 Blob 名称中指定字符或字符串分隔符来创建虚拟层次结构。
使用Blob Storage服务我们需要在配置文件写入存储资源的连接字符串,这个概念类似数据库的连接字符串。连接字符串在appSettings节点中
<add key="Microsoft.ServiceBus.Namespace" value="Endpoint=sb://<你的存储链接url>/;SharedAccessKeyName=<你的共享密钥>" /> <add key="Microsoft.WindowsAzure.Storage" value="BlobEndpoint=<你的存储资源链接>/;QueueEndpoint=<你的存储资源链接>; TableEndpoint=<你的存储资源链接>/; AccountName=<你的存储资源名称>; AccountKey=<你的存储资源访问密钥> " />
|
我们需要从NuGet获取WindowsAzure.Storage库,该库的项目地址是:https://www.nuget.org/packages/WindowsAzure.Storage,引用完成后,我们建立本章的控制器:StorageBlobController,该控制器有如下Action
- Index
-
Create
-
Delete
-
List
-
Upload
[Authorize] public class StorageBlobController : Controller { CloudStorageAccount storageAccount = CloudStorageAccount.Parse (CloudConfigurationManager.GetSetting("Microsoft.WindowsAzure.Storage"));
CloudBlobClient blobClient = null;
public StorageBlobController()
{
blobClient = storageAccount.CreateCloudBlobClient();
}
}
|
这次我们将[Authorize]加载到Controller上,意味着本次控制器的所有操作都必须经过身份验证。
一、列出当前存储账号容器
代码简单到无法直视
public ActionResult Index() { var containes = blobClient.ListContainers();
return View(containes);
}
|
对应的View
@model IEnumerable<Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("创建新的容器", "Create")
</p>
<table class="table">
<tr>
<th>Name</th>
<th>StorageUri</th>
<th>Uri</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>
@Html.ActionLink(@item.Name, "List", new { name = item.Name })
</td>
<td>@item.StorageUri</td>
<td>@item.Uri</td>
<td>
@Html.ActionLink("上传文件", "Upload", new { name = item.Name }) |
@Html.ActionLink("删除", "Delete", new { name = item.Name })
</td>
</tr>
}
</table>
|
运行结果如图
二、创建新的容器
创建新的容器之前我们必须判断有没有同名,然后设置容器访问权限
[HttpPost] public ActionResult Create(string name) { CloudBlobContainer container = blobClient.GetContainerReference(name); container.CreateIfNotExists(); container.SetPermissions(new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Blob });
return RedirectToAction("Index");
}
|
对应View的代码
@model Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient
@{ ViewBag.Title = "Create";
}
<h2>Create Cloud Blob</h2>
@using (Html.BeginForm()) { @Html.AntiForgeryToken()
@Html.ValidationSummary(true, "", new { @class = "text-danger" }) <div class="form-group"> @Html.Label ("容器名称(容器名称只能包含小写字母、数字和连字符,并且必须以字母或数字开头。 名称不能包含两个连续的连字符)") @Html.TextBox("name", "", new { @class = "form-control" }) </div> <div class="form-group"> <input type="submit" value="Create" class="btn btn-default" /> </div> }
<div> @Html.ActionLink("Back to List", "Index") </div>
|
运行后你可以添加新的容器,关键就是:容器名称只能包含小写字母、数字和连字符,并且必须以字母或数字开头。 名称不能包含两个连续的连字符。并且SetPermissions必须在CreateIfNotExists成功执行之后运行。
创建成功后返回Index
三、删除容器
删除容器非常简单,获取到容器引用,然后删除
public ActionResult Delete(string name) { blobClient.GetContainerReference(name).Delete(); return RedirectToAction("Index"); }
|
四、上传BLOB文件
现在是本章最后一节,也是最重要的一节,在本节中我们将了解到通过HTML的File将文件上传到容器中。控制器中将HttpPostedFileBase文件流上传到容器。
[HttpPost] public ActionResult Upload(string name, HttpPostedFileBase[] files) { if (files == null) { return new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest); }
CloudBlobContainer container = blobClient.GetContainerReference(name);
foreach (HttpPostedFileBase item in files)
{
string filename = Guid.NewGuid().ToString() + "." + item.FileName.Split('.').Last();
CloudBlockBlob blob = container.GetBlockBlobReference(filename);
blob.UploadFromStream(item.InputStream); }
return RedirectToAction("List", new { name = name });
}
|
对应的View,注意Form需要声明enctype = "multipart/form-data" }
@{ ViewBag.Title = "Upload"; }
<h2>Upload</h2>
@using (@Html.BeginForm("Upload", "StorageBlob", new { name = @ViewBag.Container }, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.Label("选择文件")
<input type="file" name="files" multiple/>
<input type="submit" value="上传" />
} |
你可以多上传几种文件,比如视频、音频、图片和其他文件。
五、列出容器中存储的数据
列出容器中存储的内容关键是需要将返回的对象转为CloudBlockBlob类型。在View建议你将不同类型的文件做更友好的显示,比如图片直接显示图片,音频文件直接使用HTML5的音频播发器
public ActionResult List(string name) { CloudBlobContainer container = blobClient.GetContainerReference(name);
var result = container.ListBlobs(null, false).Where (x => x.GetType() == typeof(CloudBlockBlob)).Cast<CloudBlockBlob>();
return View(result);
} |
对应的View对不同类型文件做了不同的呈现方案
@model IEnumerable<Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob>
@{
ViewBag.Title = "List";
}
<h2>List</h2>
<p>
@Html.ActionLink("上传文件", "Upload", new { name = @ViewBag.Container })
</p>
<table class="table">
<tr>
<th>Container</th>
<th>Name</th>
<th>Size</th>
<th>Type</th>
<th>Uri</th>
<th>LastDate</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>@item.Container.Name</td>
<td>@item.Name</td>
<td>@item.Properties.Length</td>
<td>@item.BlobType</td>
<td>
@{
var fileType = System.IO.Path.GetExtension(item.Name).ToLower();
if (new string[] { ".jpg", ".png" }.Any(x => x == fileType))
{
<img src="@item.Uri" />
}
else if (new string[] { ".ogg", ".mp4" }.Any(x => x == fileType))
{
<video width="320" height="240" controls="controls"> @if (fileType == "ogg")
{
<source src="@item.Uri" type="video/ogg">
}
else
{
<source src="@item.Uri" type="video/mp4">
}
Your browser does not support the video tag.
</video>
}
else if (fileType == ".mp3")
{
<audio controls="controls">
<source src="@item.Uri" type="audio/mpeg">
Your browser does not support the audio tag.
</audio>
}
else
{
<a href="@item.Uri">下载</a>
}
}
</td>
<td>@item.Properties.LastModified.Value.DateTime</td>
</tr>
}
</table>
|
运行后如图
|