Partilhar via


Parte 3: Criação de um Controlador de Administrador

por Rick Anderson

Descarregar Projeto Concluído

Adicionar um controlador de administrador

Nesta secção, vamos adicionar um controlador de API Web que suporta operações CRUD (criar, ler, atualizar e eliminar) em produtos. O controlador utilizará o Entity Framework para comunicar com a camada da base de dados. Só os administradores poderão usar este controlador. Os clientes acedem aos produtos através de outro controlador.

No Explorador de Soluções, clique com o botão direito na pasta Controladores. Seleciona Adicionar e depois Controlador.

Captura de ecrã do menu de controladores do Solutions Explorer. A opção de adicionar está selecionada e o Comando está destacado.

Na caixa de diálogo Adicionar Controlador , nomeie o controlador AdminController. Em Template, selecione "controlador API com ações de leitura/escrita, usando Entity Framework". Na classe Model, selecione "Product (ProductStore.Models)". Em Contexto de Dados, selecione "<Novo Contexto> de Dados".

Captura de ecrã da caixa de diálogo Adicionar Controlador. O menu da classe de contexto de dados está aberto e o novo contexto de dados é destacado.

Observação

Se o menu pendente da classe Model não mostrar nenhuma classe de modelo, assegure-se de que compilou o projeto. O Entity Framework utiliza reflexão, por isso necessita do assembly compilado.

Selecionar "<Novo Contexto> de Dados" abrirá o diálogo de Novo Contexto de Dados . Nomeie o contexto ProductStore.Models.OrdersContextdos dados .

Captura de ecrã do novo diálogo de contexto de dados. Uma caixa de texto mostra o nome do novo contexto de dados digitado.

Clique em OK para desligar o diálogo de Novo Contexto de Dados . No diálogo Adicionar Controlador , clique em Adicionar.

Isto é o que foi acrescentado ao projeto:

  • Uma classe chamada OrdersContext que deriva de DbContext. Esta classe fornece a ligação entre os modelos POCO e a base de dados.
  • Um controlador de API Web chamado AdminController. Este controlador suporta operações CRUD em Product instâncias. Utiliza a OrdersContext classe para comunicar com o Entity Framework.
  • Uma nova cadeia de ligação à base de dados no ficheiro Web.config.

Captura de ecrã da vista de projeto do Solutions Explorer. AdminController.cs e OrdersContext.cs estão destacados.

Abre o ficheiro OrdersContext.cs. Note que o construtor especifica o nome da cadeia de ligação à base de dados. Este nome refere-se à cadeia de ligação que foi adicionada a Web.config.

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

Adicione as seguintes propriedades à classe OrdersContext:

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

Um DbSet representa um conjunto de entidades que podem ser consultadas. Aqui está a lista completa da 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; }
}

A AdminController classe define cinco métodos que implementam funcionalidades básicas do CRUD. Cada método corresponde a um URI que o cliente pode invocar:

Método do Controlador Descrição URI Método HTTP
GetProducts Recebe todos os produtos. API/Produtos GET
GetProduct Encontra um produto por ID. api/produtos/id GET
PutProduct Atualiza um produto. api/produtos/id COLOCAR
PostProduct Cria um novo produto. API/Produtos POST
EliminarProduto Apaga um produto. api/produtos/id SUPRIMIR

Cada método chama OrdersContext para consultar a base de dados. Os métodos que modificam a coleção (PUT, POST e DELETE) pedem db.SaveChanges para persistir as alterações na base de dados. Os controladores são criados para cada pedido HTTP e, posteriormente, descartados, por isso é necessário persistir as alterações antes de um método retornar.

Adicionar um Inicializador de Base de Dados

O Entity Framework tem uma funcionalidade interessante que permite preencher a base de dados no arranque e recriá-la automaticamente sempre que os modelos mudam. Esta funcionalidade é útil durante o desenvolvimento, porque tens sempre alguns dados de teste, mesmo que mudes os modelos.

No Explorador de Soluções, clique com o botão direito na pasta Models e crie uma nova classe chamada OrdersContextInitializer. Cole a seguinte implementação:

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

Ao herdar da classe DropCreateDatabaseIfModelChanges, estamos a dizer ao Entity Framework para remover a base de dados sempre que modificarmos as classes do modelo. Quando o Entity Framework cria (ou recria) a base de dados, chama o método Seed para preencher as tabelas. Usamos o método Semente para adicionar alguns produtos de exemplo e um pedido de exemplo.

Esta funcionalidade é ótima para testes, mas não uses a classe DropCreateDatabaseIfModelChanges em produção, porque podes perder os teus dados se alguém alterar uma classe de modelo.

De seguida, abra o Global.asax e adicione o seguinte código ao método Application_Start :

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

Enviar um pedido ao controlador

Neste momento, ainda não escrevemos código cliente, mas pode invocar a API web usando um navegador web ou uma ferramenta de depuração HTTP como o Fiddler. No Visual Studio, pressione F5 para iniciar a depuração. O seu navegador web abrirá em http://localhost:*portnum*/, onde portnum é um número de porta.

Envie um pedido HTTP para "http://localhost:*portnum*/api/admin. O primeiro pedido pode demorar a ser concluído, porque o Entity Framework precisa de criar e semear a base de dados. A resposta deve ser semelhante ao seguinte:

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