如何将 Azure Blob 存储与 Azure 网站一起使用






4.67/5 (9投票s)
在 Azure 网站上托管的 ASP.NET MVC 站点上使用 Azure BLOB 存储的分步教程。
引言
Windows Azure 平台提供各种云托管服务,包括“Azure 网站”(仍处于“预览”阶段)和 Azure BLOB 存储。由于大多数 BLOB 存储教程都假定您正在使用“Azure Web 角色”,因此它们的说明并非总是适用于 Azure 网站。在本教程中,我将演示如何使用 Azure BLOB 存储来存储从托管在 Azure 网站上的 ASP.NET MVC 4 网站上传的图像。
步骤 1 – 设置 Azure 存储帐户
这在 Azure 门户中非常简单。只需创建一个存储帐户。您确实需要提供帐户名称。每个存储帐户可以有许多“容器”,因此您可以根据需要与多个站点共享同一个存储帐户。
步骤 2 – 安装 Azure SDK
这是使用 Web 平台安装程序完成的。我为 VS 2012 安装了 1.8 版本。
步骤 3 – 设置 Azure 存储模拟器
似乎对于 Azure Web 角色项目,您可以配置 Visual Studio 自动启动 Azure 存储模拟器,但我认为该选项不适用于托管在 Azure 网站上的常规 ASP.NET MVC 项目。模拟器是 csrun.exe,由于 Microsoft 似乎 在每个 SDK 版本中都移动了它,因此我花了一些时间才找到它。它需要使用 /devstore 命令行参数运行,以告诉它启动存储模拟器:
C:\Program Files\Microsoft SDKs\Windows Azure\Emulator\csrun.exe /devstore
为了方便起见,我将此命令作为选项添加到 Visual Studio 中的“永恒工具”列表中,以便我可以快速启动它。启动后,系统托盘中会出现一个新图标,让您可以访问 UI,其中显示了它正在运行的端口
步骤 4 – 设置开发连接字符串
在开发期间,我们希望使用模拟器,这需要连接字符串。对于 ASP.NET MVC 站点,我们需要直接进入 web.config 并自行输入新的连接字符串。模拟器的连接字符串非常简单:
<connectionStrings>
<add name="StorageConnection" connectionString="UseDevelopmentStorage=true"/>
</connectionStrings>
步骤 5 – 在 ASP.NET MVC 4 中上传图像
这对于大多数 Web 开发人员来说可能非常基础,但我花了一些时间才找到一个好的教程。这是如何在 Razor 语法中创建一个基本表单,让用户选择和上传文件:
@using (Html.BeginForm("ImageUpload", "Admin",
FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div>Please select an image to upload</div>
<input name="image" type="file">
<input type="submit" value="Upload Image" />
}
现在在我的 AdminController
的 ImageUpload
方法中,我可以使用 Request.Files
访问器访问上传文件的详细信息,该访问器返回 HttpPostedFileBase
的实例:
[HttpPost]
public ActionResult ImageUpload()
{
string path = @"D:\Temp\";
var image = Request.Files["image"];
if (image == null)
{
ViewBag.UploadMessage = "Failed to upload image";
}
else
{
ViewBag.UploadMessage = String.Format("Got image {0} of type {1} and size {2}",
image.FileName, image.ContentType, image.ContentLength);
// TODO: actually save the image to Azure blob storage
}
return View();
}
步骤 6 – 添加 Azure 引用
现在我们需要添加对 Microsoft.WindowsAzure.StorageClient
的项目引用,这使我们能够访问 Microsoft.WindowsAzure
和 Microsoft.WindowsAzure.StorageClient
命名空间。
步骤 7 – 连接到云存储帐户
大多数教程都会告诉您通过简单地传入连接字符串的名称来连接到您的存储帐户:
var storageAccount = CloudStorageAccount.FromConfigurationSetting("StorageConnection");
但是,由于我们使用的是 Azure 网站而不是 Web 角色,这会引发异常(“必须先调用 SetConfigurationSettingPublisher 才能使用 FromConfigurationSetting”)。有几种方法可以解决此问题,但我认为最简单的方法是调用 Parse
并直接从 Web.Config 传入连接字符串:
var storageAccount = CloudStorageAccount.Parse(
ConfigurationManager.ConnectionStrings["StorageConnection"].ConnectionString);
步骤 8 – 创建容器
我们的存储帐户可以有许多“容器”,因此我们需要提供一个容器名称。对于此示例,我将其命名为“productimages
”并授予公共访问权限。
blobStorage = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobStorage.GetContainerReference("productimages");
if (container.CreateIfNotExist())
{
// configure container for public access
var permissions = container.GetPermissions();
permissions.PublicAccess = BlobContainerPublicAccessType.Container;
container.SetPermissions(permissions);
}
您为容器选择的名称实际上必须是有效的 DSN 名称,否则您会收到一个奇怪的“请求输入之一超出范围”错误。这意味着不能使用大写字母,因此“ProductImages
”将不起作用。
注意:我用于此部分的代码(来自 Windows Azure 培训工具包的云服务介绍实验室)将 CloudBlobClient
作为静态变量,并在锁中包含初始化容器的代码。我不知道这是否是为了避免尝试创建两次容器的竞争条件,或者创建 CloudBlobClient
是否开销很大,如果可能的话应该只做一次。对 CloudBlobClient
的其他访问不在锁内完成,因此它似乎是线程安全的。
步骤 9 – 将图像保存到 BLOB
最后,我们准备好实际保存图像。我们需要给它一个唯一的名称,为此我们将使用 GUID,然后是原始扩展名,但您可以使用任何您喜欢的命名策略。在此处的 BLOB 名称中包含容器名称可以避免我们对 blobStorage.GetContainer
进行额外的调用。除了命名它之外,我们还必须设置其 ContentType
(也可在我们的 HttpPostedFileBase
上使用)并上传 HttpPostedFileBase
以流形式提供的数据。
string uniqueBlobName = string.Format("productimages/image_{0}{1}",
Guid.NewGuid().ToString(), Path.GetExtension(image.FileName));
CloudBlockBlob blob = blobStorage.GetBlockBlobReference(uniqueBlobName);
blob.Properties.ContentType = image.ContentType;
blob.UploadFromStream(image.InputStream);
注意:您必须做出的一个稍微令人困惑的选择是创建块 BLOB 还是页面 BLOB。页面 BLOB 似乎针对需要随机访问读取或写入的 BLOB(例如视频文件),而我们不需要为提供图像,因此块 BLOB 似乎是最佳选择。
步骤 10 – 查找 BLOB URI
现在我们的图像已在 BLOB 存储中,但它在哪里?我们可以在创建它之后通过调用 blob.Uri
找到它
blob.Uri.ToString();
在我们的 Azure 存储模拟器环境中,这会返回类似
http://127.0.0.1:10000/devstoreaccount1/productimages/image_ab16e2d7-5cec-40c9-8683-e3b9650776b3.jpg
步骤 11 – 查询容器内容
我们如何跟踪我们放入容器中的内容?在 Visual Studio 中,在服务器资源管理器工具窗口中,应该有一个Windows Azure 存储节点,它允许您查看模拟器上的容器和 BLOB。您也可以从那里删除 BLOB,如果您不想在代码中删除。
Azure 门户具有类似的功能,允许您管理 BLOB 容器、查看其内容和删除 BLOB。
如果您想从代码中查询容器中的所有 BLOB,您只需要以下内容
var imagesContainer = blobStorage.GetContainerReference("productimages");
var blobs = imagesContainer.ListBlobs();
步骤 12 – 创建真实的连接字符串
到目前为止,我们已经针对存储模拟器完成了所有操作。现在我们需要实际连接到我们的 Azure 存储。为此,我们需要一个真实的连接字符串,它看起来像这样
DefaultEndpointsProtocol=https;AccountName=YourAccountName;AccountKey=YourAccountKey
帐户名称是您在第一步中创建 Azure 存储帐户时输入的名称。帐户密钥可在 Azure 门户中通过单击底部的“管理密钥”链接获取。如果您想知道为什么有两个密钥以及使用哪个密钥,那只是为了让您在不停机的情况下更改密钥,因此您可以使用其中任何一个。
注意:大多数示例将 DefaultEndpointsProtocol
显示为 https,据我所知,这仅仅意味着默认情况下它返回的 URI 以 https 开头。这并不会阻止您使用 HTTP 访问同一图像。您可以随时根据自己的喜好更改连接字符串中的此值。
步骤 13 – 创建发布 Web.config 转换
为了确保我们的实时站点针对我们的 Azure 存储帐户运行,我们需要创建一个 web.config 转换,因为 Web 部署向导似乎不知道 Azure 存储帐户,因此无法像处理 SQL 连接字符串那样自动提供此功能。
这是我的 Web.Release.config 中的转换:
<connectionStrings>
<add name="StorageConnection"
connectionString="DefaultEndpointsProtocol=https;AccountName=YourAccountName;AccountKey=YourAccountKey"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
步骤 14 – 将存储帐户链接到您的网站
最后,在 Azure 门户中,我们需要确保我们的网站被允许访问我们的存储帐户。转到您的网站,选择“链接”,然后添加指向您的存储帐户的链接,这将设置必要的防火墙权限。
现在您已准备好部署您的网站并在 Azure 网站上使用 Azure BLOB 存储。