Condividi tramite


Parte 3: Creazione di un controller di Amministrazione

di Rick Anderson

Scaricare il progetto completato

Aggiungere un controller Amministrazione

In questa sezione verrà aggiunto un controller API Web che supporta operazioni CRUD (creazione, lettura, aggiornamento ed eliminazione) sui prodotti. Il controller userà Entity Framework per comunicare con il livello del database. Solo gli amministratori potranno usare questo controller. I clienti accederanno ai prodotti tramite un altro controller.

In Esplora soluzioni fare clic sulla cartella Controller. Selezionare Aggiungi e quindi Controller.

Screenshot del menu Controller di Esplora soluzioni. L'opzione aggiungi è selezionata e controller è evidenziato.

Nella finestra di dialogo Aggiungi controller assegnare al controller AdminControlleril nome . In Modello selezionare "Controller API con azioni di lettura/scrittura, usando Entity Framework". In Classe modello selezionare "Product (ProductStore.Models)". In Contesto dati selezionare "<Nuovo contesto> dati".

Screenshot della finestra di dialogo Aggiungi controller. Il menu della classe di scelta rapida dei dati è aperto e viene evidenziato un nuovo contesto dati.

Nota

Se l'elenco a discesa Classe modello non mostra alcuna classe di modello, assicurarsi di compilare il progetto. Entity Framework usa la reflection, quindi richiede l'assembly compilato.

Se si seleziona "<Nuovo contesto> dati", verrà aperta la finestra di dialogo Nuovo contesto dati . Assegnare al contesto ProductStore.Models.OrdersContextdati il nome .

Screenshot della finestra di dialogo del nuovo contesto dati. In una casella di testo viene visualizzato il nome del nuovo contesto di dati digitato.

Fare clic su OK per chiudere la finestra di dialogo Nuovo contesto dati . Nella finestra di dialogo Aggiungi controller fare clic su Aggiungi.

Ecco cosa è stato aggiunto al progetto:

  • Classe denominata OrdersContext che deriva da DbContext. Questa classe fornisce l'associazione tra i modelli POCO e il database.
  • Un controller API Web denominato AdminController. Questo controller supporta operazioni CRUD sulle Product istanze di . Usa la OrdersContext classe per comunicare con Entity Framework.
  • Nuova stringa di connessione del database nel file Web.config.

Screenshot della visualizzazione del progetto Esplora soluzioni. AdminController dot c s e OrdersContext dot c s sono evidenziati.

Aprire il file OrdersContext.cs. Si noti che il costruttore specifica il nome della stringa di connessione del database. Questo nome fa riferimento alla stringa di connessione aggiunta a Web.config.

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

Aggiungere le proprietà seguenti alla classe OrdersContext:

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

Un oggetto DbSet rappresenta un set di entità su cui è possibile eseguire query. Ecco l'elenco completo per la OrdersContext classe:

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 AdminController classe definisce cinque metodi che implementano la funzionalità CRUD di base. Ogni metodo corrisponde a un URI che il client può richiamare:

Metodo controller Descrizione URI Metodo HTTP
GetProducts Ottiene tutti i prodotti. api/products GET
GetProduct Trova un prodotto in base all'ID. api/products/id GET
PutProduct Aggiornamenti un prodotto. api/products/id PUT
PostProduct Crea un nuovo prodotto. api/products POST
DeleteProduct Elimina un prodotto. api/products/id DELETE

Ogni metodo chiama in OrdersContext per eseguire una query sul database. I metodi che modificano la raccolta (PUT, POST e DELETE) chiamano db.SaveChanges per rendere persistenti le modifiche apportate al database. I controller vengono creati per richiesta HTTP e quindi eliminati, quindi è necessario rendere persistenti le modifiche prima che venga restituito un metodo.

Aggiungere un inizializzatore di database

Entity Framework offre una funzionalità utile che consente di popolare il database all'avvio e ricreare automaticamente il database ogni volta che i modelli cambiano. Questa funzionalità è utile durante lo sviluppo, perché sono sempre disponibili alcuni dati di test, anche se si modificano i modelli.

In Esplora soluzioni fare clic con il pulsante destro del mouse sulla cartella Models e creare una nuova classe denominata OrdersContextInitializer. Incollare l'implementazione seguente:

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();
        }
    }
}

Ereditando dalla classe DropCreateDatabaseIfModelChanges , si indica a Entity Framework di eliminare il database ogni volta che si modificano le classi del modello. Quando Entity Framework crea o ricrea il database, chiama il metodo Seed per popolare le tabelle. Viene usato il metodo Seed per aggiungere alcuni prodotti di esempio e un ordine di esempio.

Questa funzionalità è ideale per i test, ma non usare la classe DropCreateDatabaseIfModelChanges nell'ambiente di produzione, perché è possibile perdere i dati se un utente modifica una classe di modello.

Aprire quindi Global.asax e aggiungere il codice seguente al metodo Application_Start :

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

Inviare una richiesta al controller

A questo punto, non è stato scritto alcun codice client, ma è possibile richiamare l'API Web usando un Web browser o uno strumento di debug HTTP, ad esempio Fiddler. In Visual Studio premere F5 per avviare il debug. Il Web browser si aprirà a http://localhost:*portnum*/, dove portnum è un numero di porta.

Inviare una richiesta HTTP a "http://localhost:*portnum*/api/admin. La prima richiesta può essere lenta da completare, perché Entity Framework deve creare ed eseguire il seeding del database. La risposta dovrebbe essere simile alla seguente:

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}]