ASP.NET Podcast Show #132 - Windows Azure Blob Storage - video
Win a ticket to the MDC in Detroit. Enter here.
ASP.NET Podcast Url: http://aspnetpodcast.com/CS11/blogs/asp.net_podcast/archive/2008/12/22/asp-net-podcast-show-132-windows-azure-blob-storage-video.aspx
Show Notes:
-
Azure SDK.
-
Vista SP1.
-
Visual studio 2008/.NET 3.5 SP1.
-
Local Development.Speed.
-
VPC.
-
Improvements are coming.
-
YMMV.
-
Project type.
-
Configuration settings.
-
Web Project.
-
Storage Client.
-
Local Development Fabric.
-
Local Development Storage.
-
Hands on Labs. This example is taken, with modifications, from the hands on labs.
Local Development Storage Setup:
Local Development Storage:
Source Code for Default.aspx.cs file:
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Configuration;
using System.Data;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using Microsoft.ServiceHosting.ServiceRuntime;
using Microsoft.Samples.ServiceHosting.StorageClient;
namespace CloudImageService_WebRole
{
public partial class _Default : System.Web.UI.Page
{
private string unknownValue = "unknown";
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
RefreshGallery();
}
}
protected void upload_Click(object sender, EventArgs e)
{
if (imageFile.HasFile)
{
status.Text = "Inserted [" + imageFile.FileName +
"] - Content Type [" + imageFile.PostedFile.ContentType + "]";
SaveImages(Guid.NewGuid().ToString(), imageName.Text, imageDescription.Text,
imageTags.Text, imageFile.FileName, imageFile.PostedFile.ContentType,
imageFile.FileBytes);
imageTags.Text = String.Empty;
imageDescription.Text = String.Empty;
imageName.Text = String.Empty;
RefreshGallery();
}
else{
status.Text = "No image file uploaded.";
}
}
private void SaveImages(string id, string name, string
description, string tags, string fileName, string contentType, byte[]
data)
{
BlobProperties properties = new BlobProperties(string.Format(CultureInfo.InvariantCulture, "image_{0}", id));
NameValueCollection metadata = new NameValueCollection();
BlobContainer container = GetContainer();
metadata["Id"] = id;
metadata["Filename"] = fileName;
metadata["ImageName"] = String.IsNullOrEmpty(name) ? unknownValue : name;
metadata["Description"] = String.IsNullOrEmpty(description) ? unknownValue : description;
metadata["Tags"] = String.IsNullOrEmpty(tags) ? unknownValue : tags;
properties.Metadata = metadata;
properties.ContentType = contentType;
BlobContents imageBlob = new BlobContents(data);
container.CreateBlob(properties, imageBlob, true);
}
protected void OnBlobDataBound(object sender, ListViewItemEventArgs e)
{
BlobContainer container = GetContainer();
if (e.Item.ItemType == ListViewItemType.DataItem)
{
Repeater metadataRepeater = e.Item.FindControl("blobMetadata") as Repeater;
BlobProperties blob = ((ListViewDataItem)(e.Item)).DataItem as BlobProperties;
NameValueCollection metadata = container.GetBlobProperties(blob.Name).Metadata;
metadataRepeater.DataSource = from key in metadata.AllKeys
select new
{
Name = key,
Value = metadata[key]
};
metadataRepeater.DataBind();
}
}
protected void OnDeleteImage(object sender, CommandEventArgs e)
{
BlobContainer container = GetContainer();
if (e.CommandName == "Delete")
{
string blobName = (string)e.CommandArgument;
if (container.DoesBlobExist(blobName))
{
container.DeleteBlob(blobName);
}
else
{
status.Text = "Item does not exist";
}
RefreshGallery();
}
}
private void RefreshGallery()
{
BlobContainer container = GetContainer();
images.DataSource = container.ListBlobs(String.Empty, false);
images.DataBind();
}
/// <summary>
/// This is code written against an early CTP.
/// It is neither production ready or a best of breed.
/// It is merely code that works today.
/// </summary>
/// <returns></returns>
private BlobContainer GetContainer()
{
string blobContainer = RoleManager.GetConfigurationSetting("ContainerName");
BlobStorage blobStorage = BlobStorage.Create(StorageAccountInfo.GetDefaultBlobStorageAccountFromConfiguration());
BlobContainer newContainer = blobStorage.GetBlobContainer(blobContainer);
if (!newContainer.DoesContainerExist())
{
newContainer.CreateContainer(null, ContainerAccessControl.Public);
}
return (newContainer);
}
}
}
Source code for Default.aspx:
<%@
Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs"
Inherits="CloudImageService_WebRole._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Azure Blob Storage Engine Page</title>
<style type="text/css">
body { font-family: Verdana; font-size: 12px; }
h1 { font-size:x-large; font-weight:bold; }
h2 { font-size:large; font-weight:bold; }
img { width:200px; height:175px; margin:2em;}
li { list-style: none; }
ul { padding:1em; }
.form { width:50em; }
.form li span {width:30%; float:left; font-weight:bold; }
.form li input { width:70%; float:left; }
.form input { float:right; }
.item { font-size:smaller; font-weight:bold; }
.item ul li { padding:0.25em; background-color:#ffeecc; }
.item ul li span { padding:0.25em; background-color:#ffffff; display:block; font-style:italic; font-weight:normal; }
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>Image Gallery (Windows Azure Blob Storage)</h1>
<div class="form">
<ul>
<li><span>Name</span><asp:TextBox ID="imageName" runat="server"/></li>
<li><span>Description</span><asp:TextBox
ID="imageDescription" runat="server"/></li>
<li><span>Tags</span><asp:TextBox ID="imageTags" runat="server"/></li>
<li><span>Filename</span><asp:FileUpload ID="imageFile" runat="server" /></li>
</ul>
<asp:Button ID="upload" runat="server" onclick="upload_Click" Text="Upload Image" />
</div>
<div>
Status: <asp:Label ID="status" runat="server" />
</div>
<asp:ListView ID="images" runat="server" OnItemDataBound="OnBlobDataBound">
<LayoutTemplate>
<asp:PlaceHolder ID="itemPlaceholder" runat="server" />
</LayoutTemplate>
<EmptyDataTemplate>
<h2>No Data Available</h2>
</EmptyDataTemplate>
<ItemTemplate>
<div class="item">
<ul style="width:40em;float:left;clear:left" >
<asp:Repeater ID="blobMetadata" runat="server">
<ItemTemplate>
<li><%# Eval("Name") %><span><%# Eval("Value") %></span></li>
</ItemTemplate>
</asp:Repeater>
<%-- UNCOMMENT THE FOLLOWING LINES FOR DELETE FUNCTIONALITY --%>
<li>
<asp:LinkButton ID="deleteBlob"
OnClientClick="return confirm('Delete image?');"
CommandName="Delete"
CommandArgument='<%# Eval("Name")%>'
runat="server" Text="Delete" oncommand="OnDeleteImage" />
</li>
</ul>
<img src="<%# Eval("Uri") %>" alt="<%# Eval("Name") %>" style="float:left"/>
</div>
</ItemTemplate>
</asp:ListView>
</div>
</form>
</body>
</html>
.csdef file:
<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="CloudImageService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
<WebRole name="WebRole">
<InputEndpoints>
<!-- Must use port 80 for http and port 443 for https when running in the cloud -->
<InputEndpoint name="HttpIn" protocol="http" port="80" />
</InputEndpoints>
<ConfigurationSettings>
<Setting name="AccountName" />
<Setting name="AccountSharedKey" />
<Setting name="BlobStorageEndpoint" />
<Setting name="QueueStorageEndpoint" />
<Setting name="TableStorageEndpoint" />
<Setting name="ContainerName" />
</ConfigurationSettings>
</WebRole>
</ServiceDefinition>
cscfg file:
<?xml version="1.0"?><ServiceConfiguration serviceName="CloudImageService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">
<Role name="WebRole">
<Instances count="1"/>
<ConfigurationSettings>
<Setting name="AccountName" value="devstoreaccount1" />
<Setting name="AccountSharedKey" value="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==" />
<Setting name="BlobStorageEndpoint" value="http://127.0.0.1:10000/" />
<Setting name="QueueStorageEndpoint" value="http://127.0.0.1:10001/" />
<Setting name="TableStorageEndpoint" value="http://127.0.0.1:10002/" />
<Setting name="ContainerName" value="storagegallery" />
</ConfigurationSettings>
</Role>
</ServiceConfiguration>