En este tutorial vamos a aprender a crear una cuenta de almacenamiento con Portal de Azure (también podremos usarlo en entorno local con la máquina virtual de Azure) en el cual vamos a crear una tabla y a manejar sus datos (listar, crear, modificar y eliminar).


Primeros pasos

Con cuenta Azure

Primero accedemos al portal de Azure. Una vez hayamos iniciado sesión con nuestra cuenta, en el menú lateral, seleccionaremos “cuentas de almacenamiento”.

ts1

Una vez dentro tendremos que añadir una nueva cuenta de almacenamiento.

ts2

Luego necesitaremos rellenar los datos necesarios y pulsamos en «Crear«.

ts3

Una vez creada la cuenta de almacenamiento, pulsaremos sobre ella y nos dirigiremos al apartado de “claves de acceso”, en el cual, podremos visualizar la clave de acceso que necesitaremos para establecer la conexión entre nuestra aplicación y la cuenta de almacenamiento.

ts4
<add key="StorageConnectionString" value="DefaultEndpointsProtocol=https;AccountName=account-name;AccountKey=account-key" />

Recuerda que necesitaremos sustituir los parámetros por nuestra clave correspondiente.

Sin cuenta Azure

Abriremos el emulador de Azure, el cual deberá estar iniciado cuando estemos usando la aplicación.

Luego,cuando sea necesario, deberemos añadir a nuestro proyecto el siguiente código:

<add key="StorageConnectionString" value="UseDevelopmentStorage=true"/>

Con esto ya estaríamos listos para comenzar a desarrollar nuestra aplicación MVC.


Creación de la aplicación

Iniciación

Abrimos Visual Studios y creamos un nuevo proyecto ASP.NET MVC, al cual llamaremos “EjemploTableStorage”.

ts6

También necesitaremos seleccionar el apartado «MVC» para que nos cree un proyecto predeterminado (Para que nos resulte más fácil la creación de la aplicación).

ts7

Lo primero que vamos a cambiar es el archivo “Web.config” para añadir en «appSettings» nuestra cadena de conexión que nos proporciona Azure (O en su defecto la conexión predeterminada del emulador).

ts8


Ahora es cuando necesitamos recuperar el fragmento de código que hemos obtenido anteriormente, y lo pegaremos.

ts9

También deberemos incluir los paquetes necesarios para el correcto funcionamiento de la aplicación (Clic derecho sobre nuestro proyecto y seleccionamos «Manage NuGet Packages«).

ts10

E instalaremos los siguientes paquetes:

ts11
ts12
ts13

Modelo

Ahora en la carpeta “Models” añadiremos una clase llamada “Videojuego.cs” (Clic derecho sobre la carpeta y pulsamos en “añadir” y pulsamos en “clase”).

Una vez creada lo primero que haremos es indicar que la clase herede de “TableEntity”. También necesitaremos añadimos el «using«:

using Microsoft.WindowsAzure.Storage.Table;

y la herencia:

public class Videojuego : TableEntity

Una vez hecho esto, podremos crear nuestra clase con los atributos que necesitemos. Tiene que quedar algo parecido al siguiente código:

        public Videojuego() { }

        private String _Estudio { get; set; }
        public String Estudio
        { 
            get
            {
                return this._Estudio;
            }
            set
            {
                this.PartitionKey = value;
                this._Estudio = value;
            }
        }
        private String _IdVideojuego { get; set; }
        public String IdVideojuego
        {
            get
            {
                return this._IdVideojuego;
            }
            set
            {
                this.RowKey = value;
                this._IdVideojuego = value;
            }
        }
        public String Nombre { get; set; }
        public String Creador { get; set; }
        public String Descripcion { get; set; }
        public DateTime FechaLanzamiento { get; set; }
        public int Precio { get; set; }
        public String Categorias { get; set; }

Repositorio

Ahora tendremos que crear a nivel de proyecto una carpeta llamada “Repositories” y añadiremos una clase llamada “RepositoryVideojuegos.cs”.

Una vez creado el archivo, no hay que olvidarse de añadir los «usings» necesarios:

using Microsoft.Azure;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;

Ahora añadiremos el constructor, el cual se encarga de instanciar la conexión con la cuenta de almacenamiento.

  CloudTable tabla;
  public RepositoryVideojuegos()
  {
    String keys = 
    CloudConfigurationManager.GetSetting("StorageConnectionString");
    //Nombre de tu conexión.
    CloudStorageAccount account = CloudStorageAccount.Parse(keys);
    CloudTableClient client = account.CreateCloudTableClient();
    this.tabla = client.GetTableReference("videojuegos");
    this.tabla.CreateIfNotExists();
  }

También añadiremos el resto de métodos encargados de realizar las principales funciones de la aplicación.

  public void CrearVideojuego(String estudio, String idvideojuego
   ,String nombre, String creador,String descripcion,DateTime fecha
   ,int precio,String categorias)
   {
     Videojuego videojuego = new Videojuego();
            videojuego.Estudio = estudio;
            videojuego.IdVideojuego = idvideojuego;
            videojuego.Nombre = nombre;
            videojuego.Creador = creador;
            videojuego.Descripcion = descripcion;
            videojuego.FechaLanzamiento = fecha;
            videojuego.Precio = precio;
            videojuego.Categorias = categorias;
     TableOperation operation = TableOperation.Insert(videojuego);
     this.tabla.Execute(operation);
   }

public Videojuego BuscarVideojuego(String partitionkey,String rowkey)
 {
   TableOperation operation = TableOperation.Retrieve<Videojuego> 
   (partitionkey, rowkey);
   TableResult result = this.tabla.Execute(operation);
   if (result.Result == null)
   {
     return null;
   }
    else
   {
       Videojuego videojuego = result.Result as Videojuego;
       return videojuego;
   }
 }

public void ModificarVideojuego(String estudio, String idvideojuego
  , String nombre, String creador, String descripcion, DateTime fecha
  ,int precio, String categorias)
{
  Videojuego videojuego = this.BuscarVideojuego(estudio, idvideojuego);
  if (videojuego != null)
    {
            videojuego.Nombre = nombre;
            videojuego.Creador = creador;
           videojuego.Descripcion = descripcion;
            videojuego.FechaLanzamiento = fecha;
           videojuego.Precio = precio;
          videojuego.Categorias = categorias;
         TableOperation operation = 
       TableOperation.Replace(videojuego);
        this.tabla.Execute(operation);
    }
  }

  public void EliminarVideojuego(String partitionkey, String rowkey)
  {
    Videojuego videojuego = this.BuscarVideojuego(partitionkey,rowkey);
    if (videojuego != null)
    {
        TableOperation operation = TableOperation.Delete(videojuego);
        this.tabla.Execute(operation);
     }
  }


  public List<Videojuego> MostrarVideojuegos()
  {
        TableQuery<Videojuego> query = new TableQuery<Videojuego();
        List<Videojuego> videojuegos = 
        this.tabla.ExecuteQuery(query).ToList();
        return videojuegos;
  }

Controlador

Necesitaremos un controlador para que la aplicación pueda acceder al repositorio y que este, pueda crear y mostrar los videojuegos. Dentro de la carpeta “Controllers” añadiremos un controlador MVC Empty (Vacío) al cual llamaremos “VideojuegosController”.

Tendremos que crear un método “Index” encargado de mostrar los datos y otros métodos llamados “Create»,»Delete»,»Edit»,»Details” que deberá dividirse en dos (Get y Post) a excepción de «Delete» y «Details»:

    public class VideojuegosController : Controller
    {
        RepositoryVideojuegos repo;
        public VideojuegosController()
        {
            this.repo = new RepositoryVideojuegos();
        }

        public ActionResult Index()
        {
            List<Videojuego> videojuegos = repo.MostrarVideojuegos();
            return View(videojuegos);
        }

        public ActionResult Create()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Create(Videojuego videojuego)
        {
            repo.CrearVideojuego(videojuego.Estudio, videojuego.IdVideojuego
            ,videojuego.Nombre, videojuego.Creador, videojuego.Descripcion, 
            videojuego.FechaLanzamiento, videojuego.Precio, videojuego.Categorias);
            return RedirectToAction("Index");
        }

        public ActionResult Details(String partition, String row)
        {
            Videojuego videojuego = repo.BuscarVideojuego(partition, row);
            return View(videojuego);
        }

        public ActionResult Edit(String partition, String row)
        {
            Videojuego videojuego = repo.BuscarVideojuego(partition, row);
            return View(videojuego);
        }

        [HttpPost]
        public ActionResult Edit(Videojuego videojuego)
        {
            repo.ModificarVideojuego(videojuego.Estudio, videojuego.IdVideojuego
            , videojuego.Nombre, videojuego.Creador, videojuego.Descripcion,
            videojuego.FechaLanzamiento, videojuego.Precio, videojuego.Categorias);
            return RedirectToAction("Index");
        }

        public ActionResult Delete(String partition, String row)
        {
            repo.EliminarVideojuego(partition, row);
            return RedirectToAction("Index");

        }

Vistas

Ahora solo nos quedan las vistas, las cuales las crearemos con “scaffolding” para que nos facilite la creación (clic derecho sobre el nombre del método y pulsando en “crear vista” y marcaremos lo siguiente).

ts14

–NOTA IMPORTANTE–

El campo “Template” deberá ser :

  • Create para crear videojuegos.
  • Details para mostrar detalles de los videojuegos.
  • Delete para eliminar los videojuegos.
  • Edit para modificar los videojuegos .
  • List para mostrar los videojuegos.

También deberemos eliminar los datos que no queremos mostrar hacer más ágil el proceso de creación y edición.

Las vistas tendrán que tener un aspecto similar a estos:

Index

@model IEnumerable<EjemploTableStorage.Models.Videojuego>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Añadir Videojuego", "Create")
</p>
@if (Model != null || Model.Count() > 0)
{
    <table class="table">
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Estudio)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.IdVideojuego)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Nombre)
            </th>
            <th></th>
        </tr>

        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Estudio)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.IdVideojuego)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Nombre)
                </td>
                <td>
                    @Html.ActionLink("Editar", "Edit", new { partition = item.PartitionKey, row = item.RowKey }) |
                    @Html.ActionLink("Detalles", "Details", new { partition = item.PartitionKey, row = item.RowKey }) |
                    @Html.ActionLink("Eliminar", "Delete", new { partition = item.PartitionKey, row = item.RowKey })
                </td>
            </tr>
        }

    </table>

}
else{
    <h4>No hay Videojuegos...</h4>
}

Create

@model EjemploTableStorage.Models.Videojuego

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>


@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>Videojuego</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.Estudio, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Estudio, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Estudio, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.IdVideojuego, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.IdVideojuego, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.IdVideojuego, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Nombre, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Nombre, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Nombre, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Creador, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Creador, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Creador, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Descripcion, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Descripcion, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Descripcion, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.FechaLanzamiento, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.FechaLanzamiento, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.FechaLanzamiento, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Precio, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Precio, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Precio, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Categorias, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Categorias, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Categorias, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Volver", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}	

Details

@model EjemploTableStorage.Models.Videojuego

@{
    ViewBag.Title = "Details";
}

<h2>Details</h2>

<div>
    <h4>Videojuego</h4>
    <hr />
    <dl class="dl-horizontal">     
        <dt>
            @Html.DisplayNameFor(model => model.Estudio)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Estudio)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.IdVideojuego)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.IdVideojuego)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Nombre)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Nombre)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Creador)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Creador)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Descripcion)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Descripcion)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.FechaLanzamiento)
        </dt>

        <dd>
              @Model.FechaLanzamiento.ToString("dd/MM/yyy")
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Precio)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Precio)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Categorias)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Categorias)
        </dd>

    </dl>
</div>
<p>
    @Html.ActionLink("Editar", "Edit", new { partition = Model.PartitionKey,row = Model.RowKey }) |
    @Html.ActionLink("Volver", "Index")
</p>

Edit

@model EjemploTableStorage.Models.Videojuego

@{
    ViewBag.Title = "Edit";
}

<h2>Edit</h2>


@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>Videojuego</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })

        <div class="form-group">
            @Html.LabelFor(model => model.Estudio, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Estudio, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Estudio, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.IdVideojuego, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.IdVideojuego, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.IdVideojuego, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Nombre, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Nombre, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Nombre, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Creador, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Creador, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Creador, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Descripcion, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Descripcion, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Descripcion, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.FechaLanzamiento, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.FechaLanzamiento, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.FechaLanzamiento, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Precio, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Precio, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Precio, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Categorias, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Categorias, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Categorias, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Volver", "Index")
</div>

Ya tendríamos todo preparado para probar nuestra aplicación.


Puntos importantes

Creo que los puntos más importantes para el desarrollo de la aplicación son:

  • Entender para qué puede utilizarse este tipo de almacenamiento(NoSQL).
  • Si no se está muy familiarizado con Portal de Azure, pueden surgir problemas a la hora de la creación de la cuenta de almacenamiento.
  • La sintaxis de creación de la tabla.

Espero que os haya servido de ayuda y no olvidéis dejad un comentario para cualquier pregunta.


Autor/a: Daniel Pizarro Cuervo

Curso: Microsoft MCSA Web Applications + Microsoft MCSD App Builder + Xamarin

Centro: Tajamar

Año académico: 2018-2019

Enlace del Proyecto: Github.

Enlace del Video: Video

Leave a Comment

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.