Hola amigos!
En días pasados en un proyecto que desarrollabamos con el equipo de iT Synergy del proyecto CPE Windows App Prendo Y Aprendo me encontré con el desafío de desarrollar la funcionalidad para subir un directorio (carpeta) desde el pc del usuario a un contenedor blob storage de Azure. Aunque encontré en internet algunos links base no lograban la implementación completa o tenían referencias obsoletas. Agradezco a las pesonas que con sus post me ayudaron para resolver el problema.
En este post les comparto la clase base de la implementación desarrollada en C#. El proyecto fue implementado con ASP.NET MVC 5.
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using Microsoft.WindowsAzure.Storage.RetryPolicies;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
namespace CPE.PrendoYAprendo.ContentManager.Models
{
/// <summary>
/// Blob storage manager class
/// </summary>
public class BlobManager
{
private readonly CloudStorageAccount _account;
private readonly CloudBlobClient _blobClient;
/// <summary>
/// Initializes a new instance of the <see cref=”BlobManager” /> class.
/// </summary>
/// <param name=”connectionStringName”>Name of the connection string in app.config or web.config file.</param>
public BlobManager(string connectionStringName)
{
_account = CloudStorageAccount.Parse(ConfigurationManager.AppSettings[“StorageConnectionString”].ToString());
_blobClient = _account.CreateCloudBlobClient();
IRetryPolicy linearRetryPolicy = new LinearRetry(TimeSpan.FromSeconds(2), 10);
_blobClient.DefaultRequestOptions.RetryPolicy = linearRetryPolicy;
}
/// <summary>
/// Updates or created a blob in Azure blobl storage
/// </summary>
/// <param name=”containerName”>Name of the container.</param>
/// <param name=”blobName”>Name of the blob.</param>
/// <param name=”content”>The content of the blob.</param>
/// <returns></returns>
public bool PutBlob(string containerName, string blobName, byte[] content)
{
return ExecuteWithExceptionHandlingAndReturnValue(
() =>
{
CloudBlobContainer container = _blobClient.GetContainerReference(containerName);
CloudBlockBlob blob = container.GetBlockBlobReference(blobName);
// Primero se convierte el array a stream
//Stream stream = new MemoryStream(content);
using (Stream stream = new MemoryStream(content))
{
blob.UploadFromStream(stream);
}
});
}
/// <summary>
/// Creates the container in Azure blobl storage
/// </summary>
/// <param name=”containerName”>Name of the container.</param>
/// <returns>True if contianer was created successfully</returns>
public bool CreateContainer(string containerName)
{
return ExecuteWithExceptionHandlingAndReturnValue(
() =>
{
CloudBlobContainer container = _blobClient.GetContainerReference(containerName);
container.Create();
});
}
/// <summary>
/// Checks if a container exist.
/// </summary>
/// <param name=”containerName”>Name of the container.</param>
/// <returns>True if conainer exists</returns>
public bool DoesContainerExist(string containerName)
{
bool returnValue = false;
ExecuteWithExceptionHandling(
() =>
{
IEnumerable<CloudBlobContainer> containers = _blobClient.ListContainers();
returnValue = containers.Any(one => one.Name == containerName);
});
return returnValue;
}
/// <summary>
/// Uploads the directory to blobl storage
/// </summary>
/// <param name=”sourceDirectory”>The source directory name.</param>
/// <param name=”containerName”>Name of the container to upload to.</param>
/// <returns>True if successfully uploaded</returns>
public bool UploadDirectory(string sourceDirectory, string containerName)
{
string[] s = containerName.Split(‘/’);
string sContainerName = s[0];
string sFolderName = s[1];
return UploadDirectory(sourceDirectory, sContainerName, sFolderName);
//return UploadDirectory(sourceDirectory, containerName, string.Empty);
}
private bool UploadDirectory(string sourceDirectory, string containerName, string prefixAzureFolderName)
{
return ExecuteWithExceptionHandlingAndReturnValue(
() =>
{
if (!DoesContainerExist(containerName))
{
CreateContainer(containerName);
}
var folder = new DirectoryInfo(sourceDirectory);
var files = folder.GetFiles();
foreach (var fileInfo in files)
{
string blobName = fileInfo.Name;
if (!string.IsNullOrEmpty(prefixAzureFolderName))
{
blobName = prefixAzureFolderName + “/” + blobName;
}
PutBlob(containerName, blobName, File.ReadAllBytes(fileInfo.FullName));
}
var subFolders = folder.GetDirectories();
foreach (var directoryInfo in subFolders)
{
var prefix = directoryInfo.Name;
if (!string.IsNullOrEmpty(prefixAzureFolderName))
{
prefix = prefixAzureFolderName + “/” + prefix;
}
UploadDirectory(directoryInfo.FullName, containerName, prefix);
}
});
}
private void ExecuteWithExceptionHandling(Action action)
{
try
{
action();
}
catch (StorageException ex)
{
var requestInformation = ex.RequestInformation;
if ((int)(System.Net.HttpStatusCode)requestInformation.HttpStatusCode != 409)
{
throw;
}
}
}
private bool ExecuteWithExceptionHandlingAndReturnValue(Action action)
{
try
{
action();
return true;
}
catch (StorageException ex)
{
var requestInformation = ex.RequestInformation;
if ((int)(System.Net.HttpStatusCode)requestInformation.HttpStatusCode == 409)
{
return false;
}
throw;
}
}
}
}
Espero les sea de ayuda.
Cordial saludo,