Parte 3: Crear un controlador de administración

Por Rick Anderson

Descargar el proyecto completado

Adición de un controlador de administración

En esta sección, agregaremos un controlador de API web que admita operaciones CRUD (crear, leer, actualizar y eliminar) en productos. El controlador usará Entity Framework para comunicarse con la capa de base de datos. Solo los administradores podrán usar este controlador. Los clientes accederán a los productos a través de otro controlador.

En el Explorador de soluciones, haga clic con el botón derecho en la carpeta Controllers. Seleccione Agregar y, a continuación, Controlador.

Screenshot of the Solutions Explorer controllers menu. The add option is selected and Controller is highlighted.

En el cuadro de diálogo Agregar controlador, asigne al controlador el nombre AdminController. En Plantilla, seleccione "Controlador de la API con acciones de lectura y escritura, que usa Entity Framework". En Clase modelo, seleccione "Producto (ProductStore.Models)". En Contexto de datos, seleccione "<Nuevo contexto de datos>".

Screenshot of the Add Controller dialogue box. The data context class menu is open and new data context is highlighted.

Nota:

Si la lista desplegable Clase modelo no muestra ninguna clase de modelo, asegúrese de compilar el proyecto. Entity Framework usa la reflexión, por lo que necesita el ensamblado compilado.

Al seleccionar "<Nuevo contexto de datos>" se abrirá el cuadro de diálogo Nuevo contexto de datos. Asigne al contexto de datos el nombre ProductStore.Models.OrdersContext.

Screenshot of the new data context dialog. A textbox shows the name of the new data context typed in.

Haga clic en Aceptar para descartar el cuadro de diálogo Nuevo contexto de datos. En el cuadro de diálogo Agregar controlador, haga clic en Agregar.

Esto es lo que se ha agregado al proyecto:

  • Una clase denominada OrdersContext que se deriva de DbContext. Esta clase proporciona el pegamento entre los modelos POCO y la base de datos.
  • Un controlador de API web denominado AdminController. Este controlador admite operaciones CRUD en instancias Product. Usa la clase OrdersContext para comunicarse con Entity Framework.
  • Una nueva cadena de conexión de base de datos en el archivo Web.config.

Screenshot of the Solutions Explorer project view. AdminController dot c s and OrdersContext dot c s are highlighted.

Abra el archivo OrdersContext.cs. Observe que el constructor especifica el nombre de la cadena de conexión de base de datos. Este nombre hace referencia a la cadena de conexión que se agregó a Web.config.

public OrdersContext() : base("name=OrdersContext")

Agregue las propiedades siguientes a la clase OrdersContext:

public DbSet<Order> Orders { get; set; }
public DbSet<OrderDetail> OrderDetails { get; set; }

DbSet representa un conjunto de entidades que se pueden consultar. Esta es la lista completa de la clase OrdersContext:

public class OrdersContext : DbContext
{
    public OrdersContext() : base("name=OrdersContext")
    {
    }

    public DbSet<Order> Orders { get; set; }
    public DbSet<OrderDetail> OrderDetails { get; set; }
    public DbSet<Product> Products { get; set; }
}

La clase AdminController define cinco métodos que implementan la funcionalidad CRUD básica. Cada método corresponde a un URI que el cliente puede invocar:

Método de controlador Descripción URI Método de HTTP
GetProducts Obtiene todos los productos. api/products OBTENER
GetProduct Busca un producto por identificador. api/products/id OBTENER
PutProduct Actualiza un producto. api/products/id PUT
PostProduct Crea un producto nuevo. api/products PUBLICAR
DeleteProduct Elimina un producto. api/products/id Delete

Cada método llama a OrdersContext para consultar la base de datos. Los métodos que modifican la colección (PUT, POST y DELETE) llaman a db.SaveChanges para conservar los cambios en la base de datos. Los controladores se crean por solicitud HTTP y, a continuación, se eliminan, por lo que es necesario conservar los cambios antes de que un método haga la devolución.

Adición de un inicializador de base de datos

Entity Framework tiene una práctica característica que le permite rellenar la base de datos al iniciarse y volver a crear automáticamente la base de datos cada vez que cambien los modelos. Esta característica es útil durante el desarrollo, ya que siempre tiene algunos datos de prueba, incluso si cambia los modelos.

En el Explorador de soluciones, haga clic con el botón derecho en la carpeta Modelos y cree una nueva clase denominada OrdersContextInitializer. Pegue la siguiente implementación:

namespace ProductStore.Models
{
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;

    public class OrdersContextInitializer : DropCreateDatabaseIfModelChanges<OrdersContext>
    {
        protected override void Seed(OrdersContext context)
        {
            var products = new List<Product>()            
            {
                new Product() { Name = "Tomato Soup", Price = 1.39M, ActualCost = .99M },
                new Product() { Name = "Hammer", Price = 16.99M, ActualCost = 10 },
                new Product() { Name = "Yo yo", Price = 6.99M, ActualCost = 2.05M }
            };

            products.ForEach(p => context.Products.Add(p));
            context.SaveChanges();

            var order = new Order() { Customer = "Bob" };
            var od = new List<OrderDetail>()
            {
                new OrderDetail() { Product = products[0], Quantity = 2, Order = order},
                new OrderDetail() { Product = products[1], Quantity = 4, Order = order }
            };
            context.Orders.Add(order);
            od.ForEach(o => context.OrderDetails.Add(o));

            context.SaveChanges();
        }
    }
}

Al heredar de la clase DropCreateDatabaseIfModelChanges, se indica a Entity Framework que quite la base de datos cada vez que modifiquemos las clases de modelo. Cuando Entity Framework crea (o vuelve a crear) la base de datos, llama al método Seed para rellenar las tablas. Usamos el método Seed para agregar algunos productos de ejemplo más un pedido de ejemplo.

Esta característica es excelente para las pruebas, pero no usa la clase DropCreateDatabaseIfModelChanges en producción, ya que podría perder los datos si alguien cambia una clase de modelo.

A continuación, abra Global.asax y agregue el código siguiente al método Application_Start:

System.Data.Entity.Database.SetInitializer(
    new ProductStore.Models.OrdersContextInitializer());

Envío de una solicitud al controlador

En este momento, no hemos escrito ningún código de cliente, pero puede invocar la API web mediante un explorador web o una herramienta de depuración HTTP como Fiddler. En Visual Studio, presione F5 para iniciar la depuración. El explorador web se abrirá en http://localhost:*portnum*/, donde portnum es un número de puerto.

Envíe una solicitud HTTP a "http://localhost:*portnum*/api/admin". La primera solicitud puede tardar en completarse, porque Entity Framework necesita crear e inicializar la base de datos. La respuesta debe ser similar a la siguiente:

HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Mon, 18 Jun 2012 04:30:33 GMT
X-AspNet-Version: 4.0.30319
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Content-Type: application/json; charset=utf-8
Content-Length: 175
Connection: Close

[{"Id":1,"Name":"Tomato Soup","Price":1.39,"ActualCost":0.99},{"Id":2,"Name":"Hammer",
"Price":16.99,"ActualCost":10.00},{"Id":3,"Name":"Yo yo","Price":6.99,"ActualCost":
2.05}]