Created
June 11, 2014 11:21
-
-
Save crowcoder/2d013b44fe6ea0c397c9 to your computer and use it in GitHub Desktop.
Azure Blob Storage Operations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using Microsoft.WindowsAzure.Storage; | |
using Microsoft.WindowsAzure.Storage.Blob; | |
using Microsoft.WindowsAzure.Storage.Auth; | |
using System.Collections.Generic; | |
using System.Drawing; | |
using System.Drawing.Imaging; | |
using System.Linq; | |
namespace Blobber | |
{ | |
public class BlobWorker | |
{ | |
private string _AcctName; | |
private string _AcctKey; | |
/// <summary> | |
/// A class with helper methods to perform storage operations. | |
/// </summary> | |
/// <param name="cnxn">The connection string to access the storage account. This is the main full access | |
/// connection string.</param> | |
public BlobWorker(string accname, string acctkey) | |
{ | |
if (string.IsNullOrWhiteSpace(accname)) | |
{ | |
throw new ArgumentNullException("The Account Name cannot be null or blank"); | |
} | |
if (string.IsNullOrWhiteSpace(acctkey)) | |
{ | |
throw new ArgumentNullException("The Account Key cannot be null or blank"); | |
} | |
_AcctKey = acctkey; | |
_AcctName = accname; | |
} | |
/// <summary> | |
/// Gets shared access signature that can be used for performing storage operations on a container. | |
/// </summary> | |
/// <param name="containerName">The name of the container to generate the sas token for.</param> | |
/// <param name="minsToExpiry">The number of minutes the sas token will expire in.</param> | |
/// <param name="delete">True if you want the consumer of the sas token to be able to delete blobs.</param> | |
/// <param name="list">True if you want the consumer of the sas token to be able to list blobs in the container</param> | |
/// <param name="none">True if you want the consumer to have no access. What is this for then????</param> | |
/// <param name="read">True if you want the consumer to have read access to the container.</param> | |
/// <param name="write">True if you want the consumer to have write access to the container.</param> | |
/// <returns></returns> | |
public string GetContainerSharedAccessSignature(string containerName, | |
int minsToExpiry, bool delete, bool list, bool none, bool read, bool write) | |
{ | |
SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy(); | |
policy.SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(minsToExpiry); | |
if (delete) | |
policy.Permissions = policy.Permissions | SharedAccessBlobPermissions.Delete; | |
if (list) | |
policy.Permissions = policy.Permissions | SharedAccessBlobPermissions.List; | |
if (none) | |
policy.Permissions = policy.Permissions | SharedAccessBlobPermissions.None; | |
if (read) | |
policy.Permissions = policy.Permissions | SharedAccessBlobPermissions.Read; | |
if (write) | |
policy.Permissions = policy.Permissions | SharedAccessBlobPermissions.Write; | |
CloudBlobContainer container = GetContainer(containerName); | |
string sasContainerToken = container.GetSharedAccessSignature(policy); | |
return container.Uri + sasContainerToken; | |
} | |
/// <summary> | |
/// Builds a url to a storage blob. Suitable for the value of an img src property | |
/// or a file download link. | |
/// </summary> | |
/// <param name="containername">The name of the container the blob is in.</param> | |
/// <param name="blobname">The full name of the blob.</param> | |
/// <param name="expiresin">Number of minutes to expire the sas token.</param> | |
/// <returns></returns> | |
public string GetSrcUrlWithSas(string containername, string blobname, int expiresin) | |
{ | |
CloudBlobContainer container = GetContainer(containername); | |
string sastoken = GetBlobSharedAccessSignature(containername, blobname, expiresin); | |
return container.Uri + "/" + blobname + sastoken; | |
} | |
public List<string> GetSrcUrlWithSasByTagNbr(string containername, string dirpath) | |
{ | |
List<string> theUrls = new List<string>(); | |
CloudBlobClient blobclnt = GetStorageAcct().CreateCloudBlobClient(); | |
CloudBlobContainer cnt = blobclnt.GetContainerReference(containername); | |
foreach (IListBlobItem item in cnt.ListBlobs(dirpath, true).ToList()) | |
{ | |
CloudBlockBlob cbb = item as CloudBlockBlob; | |
string blobname = cbb.Name; | |
string src = GetSrcUrlWithSas(cnt.Name, blobname, 10); | |
theUrls.Add(src); | |
} | |
return theUrls; | |
} | |
/// <summary> | |
/// Gets the shared access signature for a specific blob that expires in 'expiresin' minutes. | |
/// This returns a read-only signature and it can be used in an img src url to show an | |
/// image on a web page. | |
/// </summary> | |
/// <param name="containerName">The name of the container the blob is in.</param> | |
/// <param name="blobname">The full path to the blob. </param> | |
/// <param name="expiresin">Number of minutes the token will expire in.</param> | |
/// <returns>a string that is a shared access signature token.</returns> | |
/// <example> | |
/// <code> | |
/// <img src="https://[your_account].blob.core.windows.net/[container_name]/[path../file_name]?[the_sas_token]" alt="test" /> | |
/// </code> | |
/// </example> | |
public string GetBlobSharedAccessSignature(string containerName, string blobname, int expiresin) | |
{ | |
CloudBlobContainer container = GetContainer(containerName); | |
CloudBlockBlob blob = container.GetBlockBlobReference(blobname); | |
SharedAccessBlobPolicy sasConstraints = new SharedAccessBlobPolicy(); | |
sasConstraints.SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-5); | |
sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddDays(expiresin); | |
sasConstraints.Permissions = SharedAccessBlobPermissions.Read; | |
string sasBlobToken = blob.GetSharedAccessSignature(sasConstraints); | |
return sasBlobToken; | |
} | |
/// <summary> | |
/// Writes/Uploads a blob to the container specified in the sas token. | |
/// </summary> | |
/// <param name="filePath">The path to the file you want to write/upload. Its name | |
/// does not have to be what you name it in the container. | |
/// </param> | |
/// <param name="blobname">The 'path' to the blob. In Azure storage there is no physical | |
/// folder heirarchy, but if you design your blob name to look like a folder structure | |
/// you can later list blobs based on faux 'paths'. So a blob named 'images/personnel/bob.jpg' | |
/// would be listed in a container query for everything in 'images/personnel' even though | |
/// that is not really in a folder. </param> | |
/// <param name="sas">The stored access signature that gives the permissions to upload.</param> | |
public void WriteFile(string filePath, string blobname, string sas) | |
{ | |
if (File.Exists(filePath)) | |
{ | |
byte[] filebuffer = File.ReadAllBytes(filePath); | |
WriteBytes(filebuffer, blobname, sas); | |
} | |
else | |
{ | |
throw new FileNotFoundException("File : " + filePath + " does not exist"); | |
} | |
} | |
/// <summary> | |
/// Writes/Uploads a blob to the container specified in the sas token. | |
/// </summary> | |
/// <param name="blobbytes">The file to upload as a byte array.</param> | |
/// <param name="blobname">The 'path' to the blob. In Azure storage there is no physical | |
/// folder heirarchy, but if you design your blob name to look like a folder structure | |
/// you can later list blobs based on faux 'paths'. So a blob named 'images/personnel/bob.jpg' | |
/// would be listed in a container query for everything in 'images/personnel' even though | |
/// that is not really in a folder. </param> | |
/// <param name="sas">The stored access signature that gives the permissions to upload.</param> | |
public void WriteBytes(byte[] blobbytes, string blobname, string sas) | |
{ | |
CloudBlobContainer container = GetContainerFromSas(sas); | |
CloudBlockBlob blkBlob = container.GetBlockBlobReference(blobname); | |
blkBlob.UploadFromByteArray(blobbytes, 0, blobbytes.Length); | |
} | |
/// <summary> | |
/// Draws text on a blob image. | |
/// </summary> | |
/// <param name="filestr"></param> | |
/// <param name="containername"></param> | |
/// <param name="blobname"></param> | |
/// <param name="shipperinfo"></param> | |
public void WriteStream(Stream filestr, string containername, string blobname, string shipperinfo) | |
{ | |
using (Image img = Bitmap.FromStream(filestr)) | |
{ | |
using (Graphics g = Graphics.FromImage(img)) | |
{ | |
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; | |
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; | |
g.FillRectangle(Brushes.Black, 0, img.Height - 40, img.Width, 40); | |
SizeF strsize = g.MeasureString(DateTime.Now.ToString() + " " + shipperinfo, new Font("Consolas", 11)); | |
if (strsize.Width > img.Width - 10) | |
{ | |
using (Image box = new Bitmap(Convert.ToInt32(strsize.Width + 1), 45)) | |
{ | |
using (Graphics boxgraphics = Graphics.FromImage(box)) | |
{ | |
boxgraphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; | |
boxgraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; | |
boxgraphics.FillRectangle(Brushes.Black, 0, 0, box.Width, box.Height); | |
boxgraphics.DrawString( | |
DateTime.Now.ToString() + " " + shipperinfo, | |
new Font("Consolas", 11), | |
Brushes.White, | |
new RectangleF(0f,0f,(float)box.Width, (float)box.Height)); | |
// boxgraphics.ScaleTransform(img.Width - 2f / strsize.Width, 1f); | |
boxgraphics.Flush(System.Drawing.Drawing2D.FlushIntention.Sync); | |
g.DrawImage(box, new Point(0, img.Height - 30)); | |
} | |
} | |
} | |
else | |
{ | |
g.DrawString(DateTime.Now.ToString() + " " + shipperinfo, new Font("Consolas", 11), Brushes.White, new PointF(10, img.Height - 20)); | |
} | |
g.Flush(System.Drawing.Drawing2D.FlushIntention.Sync); | |
} | |
CloudBlobClient cbc = GetStorageAcct().CreateCloudBlobClient(); | |
CloudBlobContainer cbcont = cbc.GetContainerReference(containername); | |
CloudBlockBlob cbb = cbcont.GetBlockBlobReference(blobname); | |
Stream s = new MemoryStream(); | |
img.Save(s, ImageFormat.Png); | |
s.Position = 0; | |
cbb.UploadFromStream(s); | |
s.Close(); | |
s.Dispose(); | |
} | |
} | |
/// <summary> | |
/// Returns a list of strings that are anchor links for blobs in a container. | |
/// </summary> | |
/// <param name="container"></param> | |
/// <param name="prefix"></param> | |
/// <returns></returns> | |
public List<string> ListBlobsinContainer(string container, string prefix) | |
{ | |
string earl = "<a href=\"{0}\" target=\"_blank\" ><img height=\"75\" width=\"133\" src=\"{0}\" alt=\"{1}\" /></a>"; | |
List<string> theblobs = new List<string>(); | |
CloudBlobClient blobclnt = GetStorageAcct().CreateCloudBlobClient(); | |
CloudBlobContainer cnt = blobclnt.GetContainerReference(container); | |
foreach (IListBlobItem item in cnt.ListBlobs(prefix, true)) | |
{ | |
CloudBlockBlob cbb = (CloudBlockBlob)item; | |
string thename = cbb.Name; | |
string[] nametokens = cbb.Name.Split(new string[] { "/" },StringSplitOptions.None); | |
theblobs.Add(string.Format(earl, GetSrcUrlWithSas(container, cbb.Name, 1000), nametokens[nametokens.Length -1])); | |
} | |
return theblobs; | |
} | |
/// <summary> | |
/// Returns a CloudBlobContainer reference built with a storage access token. The blob URI is | |
/// restricted to the permissions of the sas token. | |
/// </summary> | |
/// <param name="containerSas"></param> | |
/// <returns></returns> | |
private Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer GetContainerFromSas(string containerSas) | |
{ | |
try | |
{ | |
CloudBlobContainer theContainer = new CloudBlobContainer(new Uri(containerSas)); | |
return theContainer; | |
} | |
catch (Exception ex) | |
{ | |
throw ex; | |
} | |
} | |
/// <summary> | |
/// Returns a CloudBlobContainer reference that is not restricted by a sas token. | |
/// </summary> | |
/// <param name="containername"></param> | |
/// <returns></returns> | |
private Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer GetContainer(string containername) | |
{ | |
CloudStorageAccount storageAccount = GetStorageAcct(); | |
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); | |
CloudBlobContainer container = blobClient.GetContainerReference(containername); | |
container.CreateIfNotExists(); | |
return container; | |
} | |
/// <summary> | |
/// Gets a CloudStorageAccount reference based on the connection string. | |
/// </summary> | |
/// <returns>CloudStorageAccount</returns> | |
/// <exception cref="System.ArgumentNullException">Connection string cannot be null</exception> | |
/// <exception cref="System.FormatException">Connection string format is incorrect</exception> | |
/// <exception cref="System.ArgumentException">Connection string is invalid</exception> | |
private CloudStorageAccount GetStorageAcct() | |
{ | |
StorageCredentials creds = new StorageCredentials(_AcctName, _AcctKey); | |
return new CloudStorageAccount(creds, true); | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment