Parte 3: Criando um controlador de Administração

por Rick Anderson

Baixar Projeto Concluído

Adicionar um controlador de Administração

Nesta seção, adicionaremos um controlador de API Web que dá suporte a operações CRUD (criar, ler, atualizar e excluir) em produtos. O controlador usará o 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.

No Gerenciador de Soluções, clique com o botão direito do mouse na pasta Controladores. Selecione Adicionar e Controlador.

Captura de tela do menu Soluções Explorer controladores. A opção adicionar está selecionada e o Controlador está realçado.

Na caixa de diálogo Adicionar Controlador , nomeie o controlador AdminControllercomo . Em Modelo, selecione "Controlador de API com ações de leitura/gravação, usando o Entity Framework". Em Classe de modelo, selecione "Produto (ProductStore.Models)". Em Contexto de Dados, selecione "<Novo Contexto> de Dados".

Captura de tela da caixa de diálogo Adicionar Controlador. O menu de classe de contexto de dados está aberto e o novo contexto de dados é realçado.

Observação

Se a lista suspensa Classe modelo não mostrar nenhuma classe de modelo, certifique-se de que você compilou o projeto. O Entity Framework usa reflexão, portanto, precisa do assembly compilado.

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

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

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 Web chamado AdminController. Esse controlador dá suporte a operações CRUD em Product instâncias. Ele usa a OrdersContext classe para se comunicar com o Entity Framework.
  • Uma nova cadeia de conexão de banco de dados no arquivo Web.config.

Captura de tela do modo de exibição soluções Explorer projeto. AdminController dot c s e OrdersContext dot c s são realçados.

Abra o arquivo OrdersContext.cs. Observe que o construtor especifica o nome da cadeia de conexão do banco de dados. Esse nome refere-se à cadeia de conexã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 listagem completa para a 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 a funcionalidade CRUD básica. Cada método corresponde a um URI que o cliente pode invocar:

Método Controller Descrição URI Método HTTP
GetProducts Obtém todos os produtos. api/products GET
GetProduct Localiza um produto por ID. api/products/id GET
PutProduct Atualizações um produto. api/products/id PUT
PostProduct Cria um produto. api/products POST
DeleteProduct Exclui um produto. api/products/id Delete (excluir)

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

Adicionar um inicializador de banco de dados

O Entity Framework tem um bom recurso que permite preencher o banco de dados na inicialização e recriar automaticamente o banco de dados sempre que os modelos forem alterados. Esse recurso é útil durante o desenvolvimento, pois você sempre tem alguns dados de teste, mesmo que altere 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 ao Entity Framework para remover o banco de dados sempre que modificarmos as classes de modelo. Quando o Entity Framework cria (ou recria) o banco de dados, ele chama o método Seed para preencher as tabelas. Usamos o método Seed para adicionar alguns produtos de exemplo mais uma ordem de exemplo.

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

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

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

Enviar uma solicitação para o controlador

Neste ponto, não escrevemos nenhum código do cliente, mas você pode invocar a API Web usando um navegador da Web ou uma ferramenta de depuração 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 é algum número de porta.

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