3부: 관리 컨트롤러 만들기
작성자: Rick Anderson
관리 컨트롤러 추가
이 섹션에서는 제품에 대한 CRUD(만들기, 읽기, 업데이트 및 삭제) 작업을 지원하는 Web API 컨트롤러를 추가합니다. 컨트롤러는 Entity Framework를 사용하여 데이터베이스 계층과 통신합니다. 관리자만 이 컨트롤러를 사용할 수 있습니다. 고객은 다른 컨트롤러를 통해 제품에 액세스합니다.
솔루션 탐색기에서 Controllers 폴더를 마우스 오른쪽 단추로 클릭합니다. 추가를 선택한 다음 컨트롤러를 선택합니다.
컨트롤러 추가 대화 상자에서 컨트롤러 AdminController
이름을 로 지정합니다. 템플릿에서 "Entity Framework를 사용하여 읽기/쓰기 작업이 있는 API 컨트롤러"를 선택합니다. 모델 클래스에서 "Product(ProductStore.Models)"를 선택합니다. 데이터 컨텍스트에서 "<새 데이터 컨텍스트>"를 선택합니다.
참고
Model 클래스 드롭다운에 모델 클래스가 표시되지 않는 경우 프로젝트를 컴파일했는지 확인합니다. Entity Framework는 리플렉션을 사용하므로 컴파일된 어셈블리가 필요합니다.
"<새 데이터 컨텍스트>"를 선택하면 새 데이터 컨텍스트 대화 상자가 열립니다. 데이터 컨텍스트의 이름을 로 지정합니다 ProductStore.Models.OrdersContext
.
확인을 클릭하여 새 데이터 컨텍스트 대화 상자를 해제합니다. 컨트롤러 추가 대화 상자에서 추가를 클릭합니다.
프로젝트에 추가된 항목은 다음과 같습니다.
- DbContext에서 파생되는 라는
OrdersContext
클래스입니다. 이 클래스는 POCO 모델과 데이터베이스 간에 접착제를 제공합니다. - 라는
AdminController
Web API 컨트롤러입니다. 이 컨트롤러는 인스턴스에서Product
CRUD 작업을 지원합니다. 클래스를OrdersContext
사용하여 Entity Framework와 통신합니다. - Web.config 파일의 새 데이터베이스 연결 문자열입니다.
OrdersContext.cs 파일을 엽니다. 생성자는 데이터베이스 연결 문자열의 이름을 지정합니다. 이 이름은 Web.config 추가된 연결 문자열을 나타냅니다.
public OrdersContext() : base("name=OrdersContext")
OrdersContext
클래스에 다음 속성을 추가합니다.
public DbSet<Order> Orders { get; set; }
public DbSet<OrderDetail> OrderDetails { get; set; }
DbSet은 쿼리할 수 있는 엔터티 집합을 나타냅니다. 클래스의 전체 목록은 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; }
}
클래스는 AdminController
기본 CRUD 기능을 구현하는 5가지 메서드를 정의합니다. 각 메서드는 클라이언트가 호출할 수 있는 URI에 해당합니다.
컨트롤러 메서드 | 설명 | URI | HTTP 메서드 |
---|---|---|---|
GetProducts | 모든 제품을 가져옵니다. | api/products | GET |
GetProduct | ID별로 제품을 찾습니다. | api/products/id | GET |
PutProduct | 제품을 업데이트. | api/products/id | PUT |
PostProduct | 새 제품을 만듭니다. | api/products | POST |
DeleteProduct | 제품을 삭제합니다. | api/products/id | DELETE |
각 메서드는 를 호출 OrdersContext
하여 데이터베이스를 쿼리합니다. 컬렉션(PUT, POST 및 DELETE) db.SaveChanges
을 수정하여 데이터베이스에 대한 변경 내용을 유지하는 메서드입니다. 컨트롤러는 HTTP 요청별로 생성된 다음 삭제되므로 메서드가 반환되기 전에 변경 내용을 유지해야 합니다.
데이터베이스 이니셜라이저 추가
Entity Framework에는 시작 시 데이터베이스를 채우고 모델이 변경될 때마다 데이터베이스를 자동으로 다시 만들 수 있는 좋은 기능이 있습니다. 이 기능은 모델을 변경하더라도 항상 일부 테스트 데이터가 있기 때문에 개발 중에 유용합니다.
솔루션 탐색기 Models 폴더를 마우스 오른쪽 단추로 클릭하고 라는 OrdersContextInitializer
새 클래스를 만듭니다. 다음 구현에 붙여 넣습니다.
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();
}
}
}
DropCreateDatabaseIfModelChanges 클래스에서 상속하여 모델 클래스를 수정할 때마다 Entity Framework에 데이터베이스를 삭제하도록 합니다. Entity Framework는 데이터베이스를 만들거나 다시 만들 때 Seed 메서드를 호출하여 테이블을 채웁니다. Seed 메서드를 사용하여 예제 제품과 예제 순서를 추가합니다.
이 기능은 테스트에 적합하지만 다른 사람이 모델 클래스를 변경하는 경우 데이터가 손실될 수 있으므로 프로덕션 환경에서 DropCreateDatabaseIfModelChanges 클래스를 사용하지 마세요.
그런 다음 Global.asax를 열고 Application_Start 메서드에 다음 코드를 추가합니다.
System.Data.Entity.Database.SetInitializer(
new ProductStore.Models.OrdersContextInitializer());
컨트롤러에 요청 보내기
이 시점에서 클라이언트 코드를 작성하지 않았지만 웹 브라우저 또는 Fiddler와 같은 HTTP 디버깅 도구를 사용하여 웹 API를 호출할 수 있습니다. Visual Studio에서 F5 키를 눌러 디버깅을 시작합니다. 웹 브라우저가 에 http://localhost:*portnum*/
열립니다. 여기서 portnum 은 일부 포트 번호입니다.
HTTP 요청을 "http://localhost:*portnum*/api/admin
로 보냅니다. Entity Framework에서 데이터베이스를 만들고 시드해야 하므로 첫 번째 요청이 완료되는 속도가 느려질 수 있습니다. 응답은 다음과 유사해야 합니다.
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}]