Parte 3: Criando um controlador de administração

por Mike Wasson

Baixar projeto concluído

Adicionar um controlador de administrador

Nesta seção, adicionaremos um controlador de API Web que oferece suporte a operações CRUD (criar, ler, atualizar e excluir) em produtos. O controlador usará Entity Framework para se comunicar com a camada de banco de dados. Somente os administradores poderão usar esse controlador. Os clientes acessarão os produtos por meio de outro controlador.

Em Gerenciador de Soluções, clique com o botão direito do mouse na pasta controladores. Selecione Adicionar e, em seguida, controlador.

Na caixa de diálogo Adicionar controlador , nomeie o controlador AdminController. Em modelo, selecione "controlador de API com ações de leitura/gravação, usando Entity Framework". Em classe de modelo, selecione "produto (ProductStore. Models)". Em contexto de dados, selecione "<novo contexto de dados>".

Note

Se a lista suspensa classe de modelo não mostrar classes de modelo, verifique se você compilou o projeto. Entity Framework usa reflexão, portanto, precisa do assembly compilado.

Se você selecionar "<novo contexto de dados>" abrirá a caixa de diálogo novo contexto de dados . Nomeie o ProductStore.Models.OrdersContextde contexto de dados.

Clique em OK para ignorar a caixa de diálogo novo contexto de dados . Na caixa de diálogo Adicionar controlador , clique em Adicionar.

Veja o que foi adicionado ao projeto:

  • Uma classe chamada OrdersContext que deriva de DbContext. Essa classe fornece a cola entre os modelos POCO e o banco de dados.
  • Um controlador de API da Web chamado AdminController. Esse controlador oferece suporte a operações CRUD em instâncias de Product. Ele usa a classe OrdersContext para se comunicar com Entity Framework.
  • Uma nova cadeia de conexão de banco de dados no arquivo Web. config.

Abra o arquivo OrdersContext.cs. Observe que o construtor Especifica o nome da cadeia de conexão do banco de dados. Esse nome se refere à cadeia de conexão que foi adicionada ao 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 listagem completa para a classe 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; }
}

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

Método de controlador DESCRIÇÃO URI Método HTTP
GetProducts Obtém todos os produtos. API/produtos GET
Getproduct Localiza um produto por ID. API/produtos/ID GET
PutProduct Atualiza um produto. API/produtos/ID PUT
Produto Cria um produto. API/produtos POST
DeleteProduct Exclui um produto. API/produtos/ID Delete (excluir)

Cada método chama OrdersContext para consultar o banco de dados. Os métodos que modificam a coleção (PUT, POST e DELETE) chamam db.SaveChanges para persistir as alterações no banco de dados. Os controladores são criados por solicitação HTTP e, em seguida, descartados, portanto, é necessário manter as alterações antes que um método seja retornado.

Adicionar um inicializador de banco de dados

Entity Framework tem um bom recurso que permite que você preencha o banco de dados na inicialização e recrie o banco de dados automaticamente sempre que os modelos forem alterados. Esse recurso é útil durante o desenvolvimento, porque você sempre tem alguns dados de teste, mesmo se você alterar os modelos.

Em Gerenciador de Soluções, clique com o botão direito do mouse na pasta modelos e crie uma nova classe chamada OrdersContextInitializer. Cole na 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 dizendo Entity Framework para descartar o banco de dados sempre que modificarmos as classes de modelo. Quando Entity Framework cria (ou recria) o banco de dados, ele chama o método semente para popular as tabelas. Usamos o método semente para adicionar alguns produtos de exemplo mais um exemplo de ordem.

Esse recurso é ótimo para teste, mas não use a classe DropCreateDatabaseIfModelChanges em produção, porque você poderá perder seus dados se alguém alterar uma classe de modelo.

Em seguida, abra global. asax e adicione o seguinte código ao aplicativo_ método de início:

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

Enviar uma solicitação para o controlador

Neste ponto, não escrevemos nenhum código de cliente, mas você pode invocar a API Web usando um navegador da Web ou uma ferramenta de depuração de HTTP, como o Fiddler. No Visual Studio, pressione F5 para iniciar a depuração. Seu navegador da Web será aberto para http://localhost:*portnum*/, em que PortNum é um número de porta.

Enviar uma solicitação HTTP para "http://localhost:*portnum*/api/admin. A primeira solicitação pode ser lenta para ser concluída, pois Entity Framework precisa criar e propagar o banco de dados. A resposta deve ter algo 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}]