# Criando WEBAPI Abra o **Visual Studio** e clique em New Project; Selecione a linguagem Visual C# ->ASP .NET Web Application; Informe o nome WebApi2_Produtos e clique no botão OK; A seguir selecione o template Web API, sem autenticação nem hospedagem na nuvem e clique em OK; ## Definindo o modelo de domínio e o Repositório de Produtos na pasta Models Vamos definir o nosso modelo de domínio representando pela classe Produtos e a seguir criar um repositório de produtos. A criação de um repositório em nosso projeto nos ajudará a centralizar a lógica de acesso aos dados e também vai desacoplar a nossa aplicação da fonte de dados ou ferramenta ORM que porventura venhamos a utilizar. Vamos criar na pasta Models a classe *Produto.cs* que será nosso modelo de domínio. Clique com o botão direito sobre a pasta Models e a seguir em Add Class. Informe o nome Produto.cs e inclua o seguinte código nesta classe: ``` public class Produto { public int Id { get; set; } public string Nome { get; set; } public string Categoria { get; set; } public decimal Preco { get; set; } } ``` A seguir inclua uma interface chamada IProdutoRepositorio.cs na mesma pasta com o seguinte código: ``` public interface IProdutoRepositorio { IEnumerable<Produto> GetAll(); Produto Get(int id); Produto Add(Produto item); void Remove(int id); bool Update(Produto item); } ``` Na interface definimos os métodos que deverá ser implementados. Agora vamos criar a classe ProdutoRepositorio.cs na mesma pasta que vai implementar essa interface. ``` using System; using System.Collections.Generic; namespace WebApi2_Produtos.Models { public class ProdutoRepositorio : IProdutoRepositorio { private List<Produto> produtos = new List<Produto>(); private int _nextId = 1; public ProdutoRepositorio() { Add(new Produto { Nome = "Guaraná Antartica", Categoria = "Refrigerantes", Preco = 4.59M }); Add(new Produto { Nome = "Suco de Laranja Prats", Categoria = "Sucos", Preco = 5.75M }); Add(new Produto { Nome = "Mostarda Hammer", Categoria = "Condimentos", Preco = 3.90M }); Add(new Produto { Nome = "Molho de Tomate Cepera", Categoria = "Condimentos", Preco = 2.99M }); Add(new Produto { Nome = "Suco de Uva Aurora", Categoria = "Sucos", Preco = 6.50M }); Add(new Produto { Nome = "Pepsi-Cola", Categoria = "Refrigerantes", Preco = 4.25M }); } public Produto Add(Produto item) { if(item == null) { throw new ArgumentNullException("item"); } item.Id = _nextId++; produtos.Add(item); return item; } public Produto Get(int id) { return produtos.Find(p => p.Id == id); } public IEnumerable<Produto> GetAll() { return produtos; } public void Remove(int id) { produtos.RemoveAll(p => p.Id == id); } public bool Update(Produto item) { if( item == null) { throw new ArgumentNullException("item"); } int index = produtos.FindIndex(p => p.Id == item.Id); if(index == -1) { return false; } produtos.RemoveAt(index); produtos.Add(item); return true; } } } ``` ## Definindo a nossa Web API Nesta classe implementamos uma lista de produtos em memória incluindo alguns produtos e definimos os métodos para obter produtos, atualizar, remover e atualizar os produtos. Definindo a nossa Web API ProdutosController na pasta Controllers Uma Web API fornece toda infraestrutura para o desenvolvimento dos serviços, faz a escolha do método a ser executado, converte as mensagens em parâmetros e os tipos adequados, aplica filtros, etc. Cada requisição por padrão terá como alvo um método dentro desta classe que processa e retorna o resultado. Clique na pasta Controllers com o botão direito do mouse e a seguir em Add -> Controller; Selecione o Scaffold : Web API 2 Controller Empty e clique no botão Add; Digite o nome ProdutosController e clique no botão Add; A seguir inclua o código abaixo neste controlador: ``` using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using WebApi2_Produtos.Models; namespace WebApi2_Produtos.Controllers { public class ProdutosController : ApiController { static readonly IProdutoRepositorio repositorio = new ProdutoRepositorio(); public IEnumerable<Produto> GetAllProdutos() { return repositorio.GetAll(); } public Produto GetProduto(int id) { Produto item = repositorio.Get(id); if (item == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } return item; } public IEnumerable<Produto> GetProdutosPorCategoria(string categoria) { return repositorio.GetAll().Where( p => string.Equals(p.Categoria, categoria, StringComparison.OrdinalIgnoreCase)); } public HttpResponseMessage PostProduto(Produto item) { item = repositorio.Add(item); var response = Request.CreateResponse<Produto>(HttpStatusCode.Created, item); string uri = Url.Link("DefaultApi", new { id = item.Id }); response.Headers.Location = new Uri(uri); return response; } public void PutProduto(int id, Produto produto) { produto.Id = id; if (!repositorio.Update(produto)) { throw new HttpResponseException(HttpStatusCode.NotFound); } } public void DeleteProduto(int id) { Produto item = repositorio.Get(id); if (item == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } repositorio.Remove(id); } } } ``` Neste código estamos usando o nosso repositório definido pela classe ProdutoRepositorio para implementar a nossa Web API 2 expondo os seguintes serviços: * GetAllProdutos - retorna todos os produtos; * GetProduto - retorna um produto; * GetProdutosPorCategoria - retorna os produtos por categoria; * PostProduto - inclui um novo produto; * PutProduto - altera um produto; * DeleteProduto - exclui um produto; Observe que os nomes dos métodos do controlador ProdutosController iniciam com o nome dos verbos HTTP (GET, POST, PUT e DELETE) isso ajuda a ASP .NET a mapear a requisição do cliente para os métodos do controller (convenção). Feito isso já podemos testar o nosso serviço REST exposto pela Web API. Lembrando que o roteamento padrão definido no arquivo WebApiConfig da pasta App_Start (mostrado abaixo) indica a rota padrão definida em routeTemplate como : a literal : api (este literal é usado para evitar conflitos com o mapeamento MVC) o nome do controlador : produtos e o id (opcional) ``` public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API configuration and services // Web API routes config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); var formatters = GlobalConfiguration.Configuration.Formatters; formatters.Remove(formatters.XmlFormatter); } } ``` O código esta indicado para forçar o envio da resposta no formato JSON. ## Testando Executando projeto iremos obter exibição da página da aplicação MVC na URL : localhost:53557/ 1- Digitando : api/produtos , obtemos todos os produtos: 2- Digitando : api/produtos/4 , obtemos o produto com id igual a 4: # Consumindo API Abrir o Visual Studio e criar um projeto MVC. Iremos consumir a Api criada anteriormente. No exemplo acima o endereço é: http://localhost:63014/api/produtos E o Help está em: http://localhost:63014/Help/Api/GET-api-Produtos ## Modelo Vamos criar na pasta Models a classe *Produto.cs* que será nosso modelo de domínio. Clique com o botão direito sobre a pasta Models e a seguir em Add Class. Informe o nome Produto.cs e inclua o seguinte código nesta classe: ``` public class Produto { public int Id { get; set; } public string Nome { get; set; } public string Categoria { get; set; } public decimal Preco { get; set; } } ``` ## Criando o controlador Criando o controlador ProdutosServicoController Vamos agora criar o controlador ContatosController onde vamos definir os métodos Action para consumir a Web API. Clique com o botão direito do mouse sobre a pasta Controllers e selecione a opção Add Controller; Na janela Add Scaffold escolha a opção MVC 5 Controller - Empty - e clique em Add; Informe o nome ContatosController e clique em Add. ## Consumindo Vamos consumir o método GET da WEB API, que permite exibir dados dos produtos, iniciando com o método que exibe todos. Para isso vamos criar o método Action Index ``` public ActionResult Index() { IEnumerable<Produto> produtos = null; using (var client = new HttpClient()) { client.BaseAddress = new Uri("http://localhost:63014/api/"); //HTTP GET var responseTask = client.GetAsync("produtos"); responseTask.Wait(); var result = responseTask.Result; if (result.IsSuccessStatusCode) { var readTask = result.Content.ReadAsAsync<IList<Produto>>(); readTask.Wait(); produtos = readTask.Result; } else { produtos = Enumerable.Empty<Produto>(); ModelState.AddModelError(string.Empty, "Erro no servidor. Contate o Administrador."); } return View(produtos); } } ``` Para poder exibir o resultado temos que criar uma view *Index.cshtml*. Para isso clique com o botão direito sobre o método Index e selecione Add View, informe o nome Index e o Model List e defina a classe de modelo como Produtos e clique em Adicionar. ## Testando Antes de executar o projeto vamos ajustar o arquivo _Layoutcshtml e a view Index da pasta /Views/Home. No primeiro vamos criar um link no arquivo _Layout.cshtml para acessar o controlador Contatos : ``` <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li>@Html.ActionLink("Home", "Index", "Home")</li> <li>@Html.ActionLink("Lista de Produtos", "Index", "ProdutosServico")</li> </ul> </div> ```