Compartir a través de


Parte 10: Actualizaciones finales de la navegación y el diseño del sitio, conclusión

por Jon Galloway

MVC Music Store es una aplicación de tutorial que presenta y explica paso a paso cómo usar ASP.NET MVC y Visual Studio para el desarrollo web.

MVC Music Store es una implementación ligera de la tienda de muestras que vende álbumes de música en línea e implementa la administración básica del sitio, el inicio de sesión de usuario y la funcionalidad de carro de la compra.

En esta serie de tutoriales se detallan todos los pasos realizados para compilar la aplicación de ejemplo ASP.NET MVC Music Store. En la parte 10 se tratan las actualizaciones finales de navegación y diseño del sitio, Conclusión.

Hemos completado toda la funcionalidad principal de nuestro sitio, pero todavía tenemos algunas características para agregar a la navegación del sitio, la página principal y la página de navegación de Store.

Crear la vista parcial resumen del carro de la compra

Queremos exponer el número de elementos en el carro de la compra del usuario en todo el sitio.

Shopping cart summary screenshot, depicting the item in the cart with its pertinent information, such as genre, artist, and price.

Podemos implementar esto fácilmente mediante la creación de una vista parcial que se agrega a nuestro Site.master.

Como se mostró anteriormente, el controlador ShoppingCart incluye un método de acción CartSummary que devuelve una vista parcial:

//
// GET: /ShoppingCart/CartSummary
[ChildActionOnly]
 public ActionResult CartSummary()
{
    var cart = ShoppingCart.GetCart(this.HttpContext);
 
    ViewData["CartCount"] = cart.GetCount();
    return PartialView("CartSummary");
}

Para crear la vista parcial CartSummary, haga clic con el botón derecho en la carpeta Views/ShoppingCart y seleccione Agregar vista. Asigne a la vista el nombre CartSummary y active la casilla "Crear una vista parcial", como se muestra a continuación.

Screenshot of the menu bar selections and options for creating a partial view of the shopping cart.

La vista parcial CartSummary es realmente sencilla: es solo un vínculo a la vista Índice ShoppingCart que muestra el número de elementos en el carro. El código completo de CartSummary.cshtml es el siguiente:

@Html.ActionLink("Cart
(" + ViewData["CartCount"] + ")",
    "Index",
    "ShoppingCart",
    new { id = "cart-status" })

Podemos incluir una vista parcial en cualquier página del sitio, incluido el patrón de sitio, mediante el método Html.RenderAction. RenderAction requiere que especifiquemos el nombre de la acción ("CartSummary") y el nombre del controlador ("ShoppingCart") como se indica a continuación.

@Html.RenderAction("CartSummary",
"ShoppingCart")

Antes de agregar esto al diseño del sitio, también crearemos el menú género para que podamos realizar todas nuestras actualizaciones Site.master a la vez.

Crear la vista parcial del menú Género

Podemos hacer que sea mucho más fácil para nuestros usuarios navegar por la tienda agregando un menú género que enumera todos los géneros disponibles en nuestra tienda.

Screenshot of the partial view genre menu, displayed at the left of the shopping cart window.

Seguiremos los mismos pasos también crear una vista parcial de GenreMenu y, a continuación, podemos agregarlas al patrón de sitio. En primer lugar, agregue la siguiente acción del controlador GenreMenu al StoreController:

//
// GET: /Store/GenreMenu
[ChildActionOnly]
 public ActionResult GenreMenu()
{
    var genres = storeDB.Genres.ToList();
    return PartialView(genres);
 }

Esta acción devuelve una lista de géneros que se mostrarán en la vista parcial, que se creará a continuación.

Nota: Hemos agregado el atributo [ChildActionOnly] a esta acción del controlador, lo que indica que solo queremos que esta acción se use desde una vista parcial. Este atributo impedirá que se ejecute la acción del controlador; para ello, vaya a /Store/GenreMenu. Esto no es necesario para las vistas parciales, pero es un procedimiento recomendado, ya que queremos asegurarnos de que nuestras acciones de controlador se usen como pretendemos. También se devuelve PartialView en lugar de View, lo que permite al motor de vista saber que no debe usar el diseño para esta vista, ya que se incluye en otras vistas.

Haga clic con el botón derecho en la acción del controlador GenreMenu y cree una vista parcial denominada GenreMenu, que está fuertemente tipada mediante la clase de datos de vista Género, como se muestra a continuación.

Screenshot of the controller actions menu used for creating the partial view that lists the genre menu.

Actualice el código de vista para la vista parcial GenreMenu para mostrar los elementos mediante una lista desordenada como se indica a continuación.

@model IEnumerable<MvcMusicStore.Models.Genre>
<ul id="categories">
    @foreach (var genre in Model)
    {
        <li>@Html.ActionLink(genre.Name,
                "Browse", "Store", 
                new { Genre = genre.Name }, null)
        </li>
    }
</ul>

Actualizar el diseño del sitio para mostrar nuestras vistas parciales

Podemos agregar nuestras vistas parciales al diseño de sitio (/Views/Shared/_Layout.cshtml) llamando a Html.RenderAction(). Los agregaremos en, así como algunos marcados adicionales para mostrarlos, como se muestra a continuación:

<!DOCTYPE html>
<html>
<head>
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/Content/Site.css")"
rel="stylesheet" 
        type="text/css" />
    <script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")"
        type="text/javascript"></script>
</head>
<body>
    <div id="header">
        <h1><a href="/">ASP.NET MVC MUSIC
STORE</a></h1>
        <ul id="navlist">
            <li class="first">
                <a href="@Url.Content("~")" id="current">
                    Home</a></li>
            <li><a href="@Url.Content("~/Store/")">Store</a></li>
            <li>@{Html.RenderAction("CartSummary", "ShoppingCart");}</li>
            <li><a href="@Url.Content("~/StoreManager/")">
                    Admin</a></li>
        </ul>        
    </div>
    @{Html.RenderAction("GenreMenu", "Store");}
    <div id="main">
        @RenderBody()
    </div>
    <div id="footer">
        built with <a href="http://asp.net/mvc">ASP.NET MVC 3</a>
    </div>
</body>
</html>

Ahora, cuando ejecutemos la aplicación, veremos el género en el área de navegación izquierda y el resumen del carro en la parte superior.

Actualizar a la página Examinar de la Tienda

La página Examinar de la Tienda es funcional, pero no se ve muy bien. Podemos actualizar la página para mostrar los álbumes en un mejor diseño actualizando el código de vista (que se encuentra en /Views/Store/Browse.cshtml) de la siguiente manera:

@model MvcMusicStore.Models.Genre
 
@{
    ViewBag.Title = "Browse Albums";
}
 
<div class="genre">
    <h3><em>@Model.Name</em> Albums</h3>
 
    <ul id="album-list">
        @foreach (var album in Model.Albums)
        {
            <li>
                <a href="@Url.Action("Details", 
                    new { id = album.AlbumId })">
                    <img alt="@album.Title" 
                        src="@album.AlbumArtUrl" />
                    <span>@album.Title</span>
                </a>
            </li>
        }
    </ul>
</div>

Aquí estamos haciendo uso de Url.Action en lugar de Html.ActionLink para que podamos aplicar formato especial al vínculo para incluir la ilustración del álbum.

Nota: Estamos mostrando una portada genérica del álbum para estos álbumes. Esta información se almacena en la base de datos y se puede editar a través del Store Manager. Le damos la bienvenida a agregar sus propias ilustraciones.

Ahora cuando navegamos a un género, veremos los álbumes mostrados en una cuadrícula con la ilustración del álbum.

Music store screenshot, showing a grid view of the albums within one genre, and the partial list view that was created on the left of the window to show of all the genres.

Actualización de la página principal para mostrar los álbumes más vendidos

Queremos presentar nuestros álbumes más vendidos en la página principal para aumentar las ventas. Realizaremos algunas actualizaciones en HomeController para controlarlo y agregaremos también algunos gráficos adicionales.

En primer lugar, agregaremos una propiedad de navegación a nuestra clase Album para que EntityFramework sepa que están asociadas. Las últimas líneas de nuestra clase Album deberían tener este aspecto:

public virtual Genre  Genre                  { get; set; }
public virtual Artist Artist                 { get; set; }
public virtual List<OrderDetail>OrderDetails { get; set; }
    }
}

Nota: Esto requerirá agregar una instrucción using para incorporar el espacio de nombres System.Collections.Generic.

En primer lugar, agregaremos un campo storeDB y las instrucciones using MvcMusicStore.Models, como en nuestros otros controladores. A continuación, agregaremos el siguiente método al HomeController, que consulta nuestra base de datos para encontrar álbumes más vendidos según OrderDetails.

private List<Album> GetTopSellingAlbums(int count)
 {
    // Group the order details by album and return
    // the albums with the highest count
    return storeDB.Albums
        .OrderByDescending(a => a.OrderDetails.Count())
        .Take(count)
        .ToList();
}

Se trata de un método privado, ya que no queremos que esté disponible como una acción de controlador. Lo incluimos en el HomeController por simplicidad, pero le animamos a mover su lógica de negocio a clases de servicio separadas según convenga.

Con eso en su lugar, podemos actualizar la acción Controlador de índice para consultar los 5 álbumes más vendidos y devolverlos a la vista.

public ActionResult Index()
{
    // Get most popular albums
    var albums = GetTopSellingAlbums(5);
 
    return View(albums);
 }

El código completo del objeto HomeController actualizado es como se muestra a continuación.

using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using MvcMusicStore.Models;
 
namespace MvcMusicStore.Controllers
{
    public class HomeController : Controller
    {
        //
        // GET: /Home/
        MusicStoreEntities storeDB = new MusicStoreEntities();
        public ActionResult Index()
        {
            // Get most popular albums
            var albums = GetTopSellingAlbums(5);
 
            return View(albums);
        }
        private List<Album> GetTopSellingAlbums(int count)
        {
            // Group the order details by album and return
            // the albums with the highest count
            return storeDB.Albums
                .OrderByDescending(a => a.OrderDetails.Count())
                .Take(count)
                .ToList();
        }
    }
}

Por último, necesitaremos actualizar la vista Índice de inicio para que pueda mostrar una lista de álbumes actualizando el tipo Modelo y agregando la lista de álbumes a la parte inferior. Aprovecharemos esta oportunidad para agregar también un encabezado y una sección de promoción a la página.

@model List<MvcMusicStore.Models.Album>
@{
    ViewBag.Title = "ASP.NET MVC Music Store";
}
<div id="promotion">
</div>
<h3><em>Fresh</em> off the grill</h3>
<ul id="album-list">
    @foreach (var album in Model)
    {
        <li><a href="@Url.Action("Details", "Store",
                new { id = album.AlbumId })">
            <img alt="@album.Title" src="@album.AlbumArtUrl" />
            <span>@album.Title</span>
</a>
        </li>
    }
</ul>

Ahora, cuando ejecutemos la aplicación, veremos nuestra página principal actualizada con álbumes más vendidos y nuestro mensaje promocional.

Music store home page screenshot, showing the list of genres in a partial left view, the top picks albums at the bottom, and a large promotional message in the center of the page.

Conclusión

Hemos visto que ASP.NET MVC facilita la creación de un sitio web sofisticado con acceso a bases de datos, pertenencia, AJAX, etc. muy rápido. Esperamos que este tutorial le haya dado las herramientas que necesita para empezar a crear sus propias aplicaciones ASP.NET MVC.