您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  要资料 文章 文库 Lib 视频 Code iProcess 课程 认证 咨询 工具 火云堂 讲座吧   成长之路  
会员   
 
   
 
  
每天15篇文章
不仅获得谋生技能
更可以追随信仰
 
 
     
   
 订阅
  捐助
无责任Windows Azure SDK .NET开发入门(五):Blob Storage服务
 
作者: 王豫翔 来源: CSDN 发布于:2015-09-25
825 次浏览     评价:      
 

摘要:无责任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>

运行后如图

   
 订阅
  捐助
 
相关文章

深度解析:清理烂代码
如何编写出拥抱变化的代码
重构-使代码更简洁优美
团队项目开发"编码规范"系列文章
 
相关文档

重构-改善既有代码的设计
软件重构v2
代码整洁之道
高质量编程规范
 
相关课程

基于HTML5客户端、Web端的应用开发
HTML 5+CSS 开发
嵌入式C高质量编程
C++高级编程
 

使用decj简化Web前端开发
Web开发框架形成之旅
更有效率的使用Visual Studio
MVP+WCF+三层结构搭建框架
ASP.NET运行机制浅析【图解】
编写更好的C#代码
10个Visual Studio开发调试技巧
更多...   

.NET框架与分布式应用架构设计
.NET & WPF & WCF应用开发
UML&.Net架构设计
COM组件开发
.Net应用开发
InstallShield

日照港 .NET Framework & WCF应用开发
神华信息 .NET单元测试
北京 .Net应用软件系统架构
台达电子 .NET程序设计与开发
赛门铁克 C#与.NET架构设计
广东核电 .Net应用系统架构
更多...   
 
 
 
 
 
每天2个文档/视频
扫描微信二维码订阅
订阅技术月刊
获得每月300个技术资源
 
 

关于我们 | 联系我们 | 京ICP备10020922号 京公海网安备110108001071号