Parte 3: Criando um controlador de Administração
por Rick Anderson
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.
Na caixa de diálogo Adicionar Controlador , nomeie o controlador AdminController
como . 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".
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.OrdersContext
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 Web chamado
AdminController
. Esse controlador dá suporte a operações CRUD emProduct
instâncias. Ele usa aOrdersContext
classe para se comunicar com o 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 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}]