El almacenamiento de BLOB en Azure o Windows Azure Storage (BLOB – Binary Large Object), es un servicio de almacenamiento que tiene Microsoft pensado para almacenar archivos multimedia de gran tamaño, de forma independiente dentro de la nube, ya que no se almacenarán en ninguna BBDD. Existen tres tipos: Blobs en páginas, Blobs en anexos y Blobs en bloques.

 

En este post vamos a aprender a almacenar las imágenes en la nube y mostrar esas imágenes en una aplicación web. Para ello primeramente tendremos que crear una cuenta de almacenamiento en Azure y dentro de ésta, el contenedor donde se guardarán las imágenes seleccionando el tipo de acceso BLOB o público para poder tener acceso desde el exterior. Para esto les dejo un link de Microsoft con los pasos necesarios: https://docs.microsoft.com/es-es/azure/storage/storage-create-storage-account

 

NOTA: Debemos guardar el nombre de la cuenta de almacenamiento y la clave primaria que necesitaremos más adelante para poder conectar el proyecto con Azure.

 

1.nombre_clave Almacenamiento de BLOB en Azure

Teniendo esto terminado podemos empezar con la parte entretenida:

 

Para empezar, en Visual Studio crearemos una aplicación web, un nuevo proyecto ASP.NET, con una plantilla MVC. Seguidamente, en la página de Index en la zona Home, que es la primera que se muestra al compilar el proyecto, eliminamos todo el código innecesario y crearemos un formulario sencillo de método POST, con dos inputs, uno de tipo “file” y otro de tipo “submit”. Quedando de la siguiente forma:

 

@{
     ViewBag.Title = “Home Page”;
}
<div class=”row”>
    <div class=”col-md-8″>
    <h2 class=”title”>Almacenamiento de imagenes</h2>
    <div>
        @using (Html.BeginForm(“UploadFile”, “Home”, FormMethod.Post, new {enctype = “multipart/form-data”}))
        {
            <input type=”file” name=”file” class=”form-control file-caption” required=””>
            <br/>
            <input type=”submit” name=”Submit” id=”Submit” value=”Almacenar” class=”btn btn-info” >
        }
        </div>
    </div>
</div>

 

Notemos que utilizamos Razor: Html.BeginForm para poder llamar un método más adelante en un ActionResult, sin necesidad de tener una vista, que nombramos UploadFile y enviamos los datos del formulario con el submit del botón.

 

A continuación, necesitaremos instalar 2 paquetes en el proyecto para poder continuar, uno es “WindowsAzure.Storage” y el otro “Microsoft.WindowsAzure.ConfigurationManager“, para hacer esto hacemos clic derecho sobre la solución, administrar paquetes NuGet, y en el apartado de Examinar buscamos los paquetes por su nombre y los instalamos.

 

2.nuGet Almacenamiento de BLOB en Azure

3.paquetes Almacenamiento de BLOB en Azure

Ahora, ya estamos listos para darle funcionalidad al proyecto,

 

Y para hacerlo de una forma sencilla y rápida iremos al HomeController y crearemos un ActionResult que llamaremos UploadFile (igual al método del formulario en la vista Index) que será el encargado de subir la foto al contenedor que creamos anteriormente en Azure. No podemos olvidar hacer las instrucciones using necesarios en la parte superior.

 

[HttpPost]
public ActionResult UploadFile()
{
    var file = Request.Files[0];
    if (file != null && file.ContentLength > 0)
    {
        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings [“StorageConnection”].ConnectionString);
        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
        CloudBlobContainer container = blobClient.GetContainerReference(“blobimages”);
        CloudBlockBlob blockBlob = container.GetBlockBlobReference(file.FileName);
        blockBlob.UploadFromStream(file.InputStream);
    }
    return RedirectToAction(“Index”);
}

 

Using necesarios:

using System.Configuration;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;

 

En este código, primero comprobamos si se ha añadido algún fichero, aunque en el formulario lo hayamos puesto como campo requerido, y si existe crearemos una conexión con Azure y le pasamos el nombre de esta cadena de conexión que crearemos en el web.config más adelante. También debemos crear un cliente de tipo CloudBlobClient y lo instanciamos dentro de un CloudBlobContainer haciendo referencia al contenedor que creamos en Azure por su nombre. Por último, tomamos el nombre del fichero que estamos subiendo y hacemos la subida del fichero indicándole file.InputStream para que sea más eficiente.

 

Por último, debemos añadir la cadena de conexión en el web.config, para ello necesitaremos el nombre y la clave primaria que guardamos de Azure. No es necesario eliminar la cadena de conexión creada por defecto.

 

<connectionStrings>
    <add name=”StorageConnection”connectionString=”DefaultEndpointsProtocol=https;AccountName=blobazureimage;AccountKey=CLAVE”></add>
</connectionStrings>

 

Llegado a este punto, ya podemos compilar nuestro proyecto y subir una imagen a nuestro contenedor de Azure.

 

Sin embargo, eso no es todo lo que podemos hacer, también podemos mostrar las imágenes que tenemos en el contenedor ya sea en un listado o en un popup, he interactuar a través de la aplicación web en caso de que queramos, por ejemplo, eliminar alguna de estas imágenes. Si quieres tener ese plus en tu aplicación sigue leyendo…

 

Primero vamos a crear una clase llamada Imagen, para poder manipular mejor el objeto dentro del Controller y poder crear listas que necesitaremos para mostrar todas las imágenes que subamos, esta clase la creamos en la carpeta Models del proyecto.

 

4.addClass Almacenamiento de BLOB en Azure

5.createClass Almacenamiento de BLOB en Azure

 

Le pondremos como propiedades Nombre y Url que son los datos que necesitamos y quedaría así:

 

namespace BLOBAzure.Models
{
    public class Imagen
    {
        public Imagen() { }
        public Imagen(String nombre, String urlimg)
        {
            this.Nombre = nombre;
            this.UrlImg = urlimg;
        }
 
        public String Nombre { get; set; }
        public String UrlImg { get; set; }
    }
}

 

Ahora, regresaremos al HomeControler y para que no nos sea muy complicado de manejar, vamos a modificar solo el ActionResult del Index, primeramente, vamos a crear fuera de todos los ActionResult una lista de la clase Imagen, para utilizarla dentro del index y la tenemos accesible en todo el HomeController en caso de que la necesitemos.

List<Imagen> imglist = new List<Imagen>();

 

También debemos añadir el using del nombre_proyecto.Models, para poder utilizar la clase

using BLOBAzure.Models;

 

Ya en el Index, lo que queremos lograr es mostrar al cargar la página un listado con los nombres de las imágenes, en caso de existir alguna, y que en cada imagen tengamos la posibilidad de ver la imagen o eliminarla.

 

public ActionResult Index(String nombre)
{
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings[“StorageConnection”].ConnectionString);
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
    CloudBlobContainer container = blobClient.GetContainerReference(“blobimages”);
    if (nombre != null)
    {
        CloudBlockBlob blockBlob = container.GetBlockBlobReference(nombre);
        blockBlob.Delete();
        foreach (IListBlobItem item in container.ListBlobs(null, true))
        {
            if (item.GetType() == typeof(CloudBlockBlob))
            {
                CloudBlockBlob blob = (CloudBlockBlob)item;
                Imagen img = new Imagen(blob.Name, blob.Uri.AbsoluteUri);
                this.imglist.Add(img);
            }
        }
        return View(imglist);
    }
    else
    {
    foreach (IListBlobItem item in container.ListBlobs(null, true))
    {
        if (item.GetType() == typeof(CloudBlockBlob))
        {
            CloudBlockBlob blob = (CloudBlockBlob)item;
            Imagen img = new Imagen(blob.Name, blob.Uri.AbsoluteUri);
            this.imglist.Add(img);
        }
    }
    return View(imglist);
    }
}

 

Aquí les dejo la explicación de este código que acabamos de ver:

 

Primeramente, le decimos que recibirá un parámetro de tipo String que llamamos nombre, que será el nombre da la imagen que queramos eliminar. Como en este caso el nombre de la imagen es único para cada uno, no necesitamos ningún id. Preguntaremos si este nombre es null, ya que no siempre tiene porque recibirlo al recargar la página.

 

En la primera parte del If, que es si recibimos un nombre de imagen para eliminar, creamos un CloudBlockBlob que tendrá el nombre de la imagen dentro del contenedor y en la siguiente línea lo eliminamos. Con esto, ya habríamos eliminado la imagen, pero en nuestro caso como mostramos un listado en tiempo real necesitaríamos recorrer todo el contenedor en la nube para guardar las imágenes que existan en la lista y poderlas mostrar en la vista.

 

Para recorrer el contenedor hacemos el foreach, y como sabemos qué tipo de blob tenemos solo necesitaríamos el if para mostrar las de tipo CloudBlockBlob, y de estas recuperamos el nombre y la url y lo añadimos a la lista. Por último devolvemos la vista pasándole la lista

 

En el else, que es cuando no se recibe ningún parámetro, pues es lo mismo, recorremos el contenedor, recuperamos las imágenes que hayan, las guardamos en la lista y la retornamos a la vista.

 

Con esto tendremos listo el Controller y solo nos faltaría dibujar en la vista a nuestro gusto. Para tener acceso a la lista y poder dibujarla primero tenemos que añadir el model.

@model List<BLOBAzure.Models.Imagen>

 

Después, para acceder a la lista y mostrar todos los elementos hacemos un foreach, yo he decidido pintarla en una lista de definición con una etiqueta <a href> llamando a una función de Sweetalert para mostrar la imagen en un popup, y un ActionLink para enviar el nombre de la imagen que queramos eliminar al controlador, y así es como quedaría:

 

@if (Model != null)
{
    <dl>
        <h4>Lista de imágenes en la nube:</h4>
        @foreach (var img in Model)
        {
            <dd>
                <span>@img.Nombre | </span>
                <a href=”#” onclick=”verFoto(‘@img.UrlImg‘)”>Ver</a>
                <span></span>
                @Html.ActionLink(“Eliminar”, “Index”, “Home”, new {nombre = @img.Nombre}, null)
            <dd>
        }
    <dl>
}

 

NOTA: No olvidemos que debemos preguntar antes si el Model es null, para que no nos dé un error al dibujar la lista.

 

Finalmente, ya tenemos el proyecto terminado y funcional, ya es hora de ver que tal nos quedó y probarlo. Por mi parte espero que les haya sido de utilidad y les dejo unas imágenes completas de la vista, clase y controlador.

 

6.fullClass Almacenamiento de BLOB en Azure

7.fullView Almacenamiento de BLOB en Azure

8.fullcontroller Almacenamiento de BLOB en Azure

 

 

 

Descripción: Con este Post y Video tutorial se pretende enseñar como almacenar y mostrar archivos multimedia en un servicio de almacenamiento de BLOB en Azure.
Autora: Lis M. Fernández Gómez.
Curso: Microsoft MCSD Web Applications + SharePoint Apps.
Centro: Tajamar.
Año académico: 2016-2017.