Aplicação ASP.NET MVC Cliente de Aplicação Web...

13
Aplicação ASP.NET MVC Cliente de Aplicação Web API (com Class Library) http://www.asp.net/web-api/overview/advanced/calling-a-web-api-from-a-net-client Calling a Web API From a .NET Client in ASP.NET Web API 2 (C#) Vamos criar: uma Class Library com o modelo de dados, uma Aplicação Web API 2 com uma Referência para a Class Library, e uma Aplicação Web MVC 5 também com uma Referência para a Class Library, cliente da aplicação Web API 2 As vantagens de usar Class library são a reutilização do componente e a garantia de que as classes do modelo de dados são iguais nas duas aplicações web. Estes três projetos podem ser criados numa mesma Solução Visual Studio ou em Soluções diferentes. Numa máquina menos potente é aconselhável criar uma única Solução para todos os projetos pois permite executar cliente e servidor tendo apenas uma única instância do Visual Studio aberta. 1. Criar a Solução Visual Studio 2015 > File > New Project… > Templates: abrir Other Project Types > Visual Studio Solutions > Blank Solution Name: Livros 2. Criar a Class Library Bt. dir. do rato em cima do nome da solução: Add > New Project… > Visual C# > Class Library Name: ClassLibraryLivros OK 3. Criar a Aplicação ASP.NET Web API 2 Bt. dir. do rato em cima do nome da solução: Add > New Project… > Web > ASP.NET Web Application Name: WebApiLivros OK ASP.NET 4.6 Templates: Web API OK 4. Criar a Aplicação ASP.NET MVC 5 (Cliente da Aplicação Web API 2) Bt. dir. do rato em cima do nome da solução: Add > New Project… > Web > ASP.NET Web Application Name: ClienteMvcLivros OK ASP.NET 4.6 Templates: MVC OK

Transcript of Aplicação ASP.NET MVC Cliente de Aplicação Web...

Page 1: Aplicação ASP.NET MVC Cliente de Aplicação Web …mouta/ARQSI-2016-2017-1Sem/Asp.NET/Aplicac… · 2. Criar a Aplicação Asp.Net Web API 2 Visual Studio 2015 > File > New > Project…

Aplicação ASP.NET MVC Cliente de Aplicação Web API (com Class Library)

http://www.asp.net/web-api/overview/advanced/calling-a-web-api-from-a-net-client

Calling a Web API From a .NET Client in ASP.NET Web API 2 (C#)

Vamos criar:

uma Class Library com o modelo de dados,

uma Aplicação Web API 2 com uma Referência para a Class Library, e

uma Aplicação Web MVC 5 também com uma Referência para a Class Library, cliente

da aplicação Web API 2

As vantagens de usar Class library são a reutilização do componente e a garantia de que as

classes do modelo de dados são iguais nas duas aplicações web.

Estes três projetos podem ser criados numa mesma Solução Visual Studio ou em Soluções

diferentes.

Numa máquina menos potente é aconselhável criar uma única Solução para todos os projetos

pois permite executar cliente e servidor tendo apenas uma única instância do Visual Studio

aberta.

1. Criar a Solução

Visual Studio 2015 > File > New Project… > Templates: abrir Other Project Types > Visual Studio Solutions > Blank Solution Name: Livros

2. Criar a Class Library Bt. dir. do rato em cima do nome da solução:

Add > New Project… > Visual C# > Class Library

Name: ClassLibraryLivros

OK

3. Criar a Aplicação ASP.NET Web API 2

Bt. dir. do rato em cima do nome da solução:

Add > New Project… > Web > ASP.NET Web Application Name: WebApiLivros OK ASP.NET 4.6 Templates: Web API OK

4. Criar a Aplicação ASP.NET MVC 5 (Cliente da Aplicação Web API 2)

Bt. dir. do rato em cima do nome da solução:

Add > New Project… > Web > ASP.NET Web Application Name: ClienteMvcLivros OK ASP.NET 4.6 Templates: MVC OK

Page 2: Aplicação ASP.NET MVC Cliente de Aplicação Web …mouta/ARQSI-2016-2017-1Sem/Asp.NET/Aplicac… · 2. Criar a Aplicação Asp.Net Web API 2 Visual Studio 2015 > File > New > Project…

Em seguida vamos criar Soluções diferentes para cada projeto.

1. Criar a Class Library

Visual Studio 2015 > File > New > Project… Visual C# > Class Library [ Type: Visual C#, A project for creating a C# class library (.dll) ]

Name: ClassLibraryLivros

1.1. Adicionar as classes Editora e Livro

ClassLibraryLivros > botão direito do rato em cima do nome do projeto: Add > Class… > Name: Editora.cs Add public class Editora { public int EditoraId { get; set; } public string Nome { get; set; } }

Add > Class… > Name: Livro.cs Add public class Livro { public int LivroId { get; set; } public string Titulo { get; set; } public int EditoraId { get; set; } public Editora Editora { get; set; } }

1.2. Build da Solução

Build > Build Solution

Page 3: Aplicação ASP.NET MVC Cliente de Aplicação Web …mouta/ARQSI-2016-2017-1Sem/Asp.NET/Aplicac… · 2. Criar a Aplicação Asp.Net Web API 2 Visual Studio 2015 > File > New > Project…

2. Criar a Aplicação Asp.Net Web API 2

Visual Studio 2015 > File > New > Project… Visual C#, Web > ASP.NET Web Application (.NET Framework)

Name: WebAPILivros

ASP.NET 4.6 Templates: Web API Authentication: Individual User Accounts OK

2.1 Adicionar uma Referência para a biblioteca ClassLibraryLivros

Adicionar o projeto ClassLibraryLivros à solução Visual Studio:

Solution ‘WebAPILivros’ (1 project) > bt. dir. do rato

Add > Existing Project… > ClassLibraryLivros.csproj > Abrir

Solution ‘WebAPILivros’ (2 projects)

Adicionar uma referência da aplicação WebAPILivros para a biblioteca ClassLibraryLivros:

WebAPILivros > bt. dir. do rato > Add > Reference…

Projects, Solution > selecionar ClassLibraryLivros > OK

2.2 Build da Aplicação

Necessário para em seguida o scaffolding poder usar as classes do modelo e do contexto.

Build > Build Solution

2.3 Scaffolding para criar Controladores para as entidades Editora e Livro

Controllers > botão direito do rato: Add > Controller… >

Add Scaffold: Web API 2 Controller with actions, using Entity Framework > Add

Model class: Editora (ClassLibraryLivros) Data context class: ApplicationDbContext (WebApiLivros.Models) Use async controller actions Controller name: EditorasController Add

Controllers > botão direito do rato: Add > Controller… >

Add Scaffold: Web API 2 Controller with actions, using Entity Framework > Add

Model class: Livro (ClassLibraryLivros) Data context class: ApplicationDbContext (WebApiLivros.Models) Use async controller actions Controller name: LivrosController Add

Page 4: Aplicação ASP.NET MVC Cliente de Aplicação Web …mouta/ARQSI-2016-2017-1Sem/Asp.NET/Aplicac… · 2. Criar a Aplicação Asp.Net Web API 2 Visual Studio 2015 > File > New > Project…

2.4 Verificar a criação de objetos DbSet para acesso à base de dados (na classe ApplicationDbContext)

No ficheiro Models\IdentityModels.cs aparecem 2 propriedades DbSet: Editoras e Livroes.

public class ApplicationDbContext : IdentityDbContext<ApplicationUser> { public ApplicationDbContext() : base("DefaultConnection", throwIfV1Schema: false) { } public static ApplicationDbContext Create() { return new ApplicationDbContext(); } public System.Data.Entity.DbSet<WebApiLivros.Models.Editora> Editoras { get; set; } public System.Data.Entity.DbSet<WebApiLivros.Models.Livro> Livroes { get; set; } }

2.5 Criar a base de dados com Migrações (ou executando a aplicação)

Criar a base de dados com Migrações:

Visual Studio 2015 > Tools > Nuget Package Manager > Package Manager Console

PM> enable-migrations

PM> add-migration Initial

PM> update-database

2.6 Executar a aplicação ou testar com Postman

Debug > Start Without Debugging Na barra de endereços do browser acrescentar /api/Editoras ou /api/Livros localhost:xxxxx/api/Editoras localhost:xxxxx/api/Livros

Page 5: Aplicação ASP.NET MVC Cliente de Aplicação Web …mouta/ARQSI-2016-2017-1Sem/Asp.NET/Aplicac… · 2. Criar a Aplicação Asp.Net Web API 2 Visual Studio 2015 > File > New > Project…

3. Criar a Aplicação ASP.NET MVC 5 (Cliente da Aplicação Web API 2)

Visual Studio 2015 > File > New Project… > Web > ASP.NET Web Application Name: ClienteMvcLivros OK ASP.NET 4.6 Templates: MVC OK

3.1 Adicionar uma Referência para a biblioteca ClassLibraryLivros

Adicionar o projeto ClassLibraryLivros à solução Visual Studio:

Solution ‘ClienteMvcLivros’ (1 project) > bt. dir. do rato

Add > Existing Project… > ClassLibraryLivros.csproj > Abrir

Solution ‘ClienteMvcLivros’ (2 projects)

Adicionar uma referência da aplicação ClienteMvcLivros para a biblioteca ClassLibraryLivros:

ClienteMvcLivros > bt. dir. do rato > Add > Reference…

Projects, Solution > selecionar ClassLibraryLivros > OK

3.2 Build da Aplicação

Necessário para em seguida o scaffolding poder usar as classes do modelo e do contexto.

Build > Buil Solution

3.3 Scaffolding para criar Controladores e Vistas Controllers > botão direito do rato: Add > Controller… >

Add Scaffold: MVC 5 Controller with views, using Entity Framework > Add

Model class: Editora (ClassLibraryLivros) Data context class: ApplicationDbContext (ClienteMvcLivros.Models) Use async controller actions Controller name: EditorasController Add

Controllers > botão direito do rato: Add > Controller… >

Add Scaffold: MVC 5 Controller with views, using Entity Framework > Add

Model class: Livro (ClasLibraryLivros) Data context class: ApplicationDbContext (ClienteMvcLivros.Models) Use async controller actions Controller name: LivrosController Add

Page 6: Aplicação ASP.NET MVC Cliente de Aplicação Web …mouta/ARQSI-2016-2017-1Sem/Asp.NET/Aplicac… · 2. Criar a Aplicação Asp.Net Web API 2 Visual Studio 2015 > File > New > Project…

3.4 Alterar a classe EditorasController

Para que esta classe possa fazer pedidos ao serviço Web API necessitámos de um cliente. A

classe HttpClient pode ser usada quer para aplicações Web, aplicações de Consola ou

aplicações móveis.

Como vamos necessitar desta classe em todas as ações de todos os controladores vamos

escrever uma classe helper para inicializar este cliente.

3.4.1 Criar uma pasta Helpers para conter a classe de acesso à Web API

ClienteMvcLivros> botão direito do rato: Add > New Folder > Helpers

Helpers > botão direito do rato: Add > Class… > Name: WebApiHttpClient.cs Add

using System; using System.Net.Http;

namespace ClienteMvcLivros.Helpers { public class WebApiHttpClient { public const string WebApiBaseAddress = "http://localhost:1742/"; public static HttpClient GetClient() { HttpClient client = new HttpClient(); client.BaseAddress = new Uri(WebApiBaseAddress); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json")); return client; } } } Necessário mudar a localização do serviço Web API na constante WebApiBaseAddress.

Configurámos no objeto HttpClient:

a propriedade BaseAddress com o endereço do serviço Web API

a propriedade DefaultRequestHeaders para que o formato da resposta do serviço seja

apenas o formato JSON. Começámos por fazer Clear() e depois adicionámos o formato

"application/json"

Page 7: Aplicação ASP.NET MVC Cliente de Aplicação Web …mouta/ARQSI-2016-2017-1Sem/Asp.NET/Aplicac… · 2. Criar a Aplicação Asp.Net Web API 2 Visual Studio 2015 > File > New > Project…

3.4.2 Classe EditorasController

using System.Collections.Generic; using System.Threading.Tasks; using System.Net; using System.Web.Mvc; using ClienteMvcLivros.Models; using ClienteMvcLivros.Helpers; using System.Net.Http; using Newtonsoft.Json;

using ClassLibraryLivros;

namespace ClienteMvcLivros.Controllers { public class EditorasController : Controller { // private ApplicationDbContext db = new ApplicationDbContext(); // GET: Editoras

. . .

3.4.3 Método Index de EditorasController

Inicial: // GET: Editoras public async Task<ActionResult> Index() { return View(await db.Editoras.ToListAsync()); }

Alterar para:

// GET: Editoras public async Task<ActionResult> Index() { var client = WebApiHttpClient.GetClient(); HttpResponseMessage response = await client.GetAsync("api/Editoras"); if (response.IsSuccessStatusCode) { string content = await response.Content.ReadAsStringAsync(); var editoras = JsonConvert.DeserializeObject<IEnumerable<Editora>>(content); return View(editoras); } else { return Content("Ocorreu um erro: " + response.StatusCode); } }

Page 8: Aplicação ASP.NET MVC Cliente de Aplicação Web …mouta/ARQSI-2016-2017-1Sem/Asp.NET/Aplicac… · 2. Criar a Aplicação Asp.Net Web API 2 Visual Studio 2015 > File > New > Project…

3.4.4 Método Details de EditorasController

Inicial:

// GET: Editoras/Details/5

public async Task<ActionResult> Details(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Editora editora = await db.Editoras.FindAsync(id); if (editora == null) { return HttpNotFound(); } return View(editora); }

Alterar para:

// GET: Editoras/Details/5 public async Task<ActionResult> Details(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } var client = WebApiHttpClient.GetClient(); HttpResponseMessage response = await client.GetAsync("api/Editoras/" + id); if (response.IsSuccessStatusCode) { string content = await response.Content.ReadAsStringAsync(); var editora = JsonConvert.DeserializeObject<Editora>(content); if (editora == null) return HttpNotFound(); return View(editora); } else { return Content("Ocorreu um erro: " + response.StatusCode); } }

3.4.5 Métodos Create de EditorasController

Inicial:

// GET: Editoras/Create public ActionResult Create() { return View(); } // POST: Editoras/Create // To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see http://go.microsoft.com/fwlink/?LinkId=317598.

Page 9: Aplicação ASP.NET MVC Cliente de Aplicação Web …mouta/ARQSI-2016-2017-1Sem/Asp.NET/Aplicac… · 2. Criar a Aplicação Asp.Net Web API 2 Visual Studio 2015 > File > New > Project…

[HttpPost] [ValidateAntiForgeryToken] public async Task<ActionResult> Create( [Bind(Include = "EditoraId,Nome")] Editora editora) { if (ModelState.IsValid) { db.Editoras.Add(editora); await db.SaveChangesAsync(); return RedirectToAction("Index"); } return View(editora); }

Alterar para:

// GET: Editoras/Create public ActionResult Create() { return View(); } // POST: Editoras/Create // To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see http://go.microsoft.com/fwlink/?LinkId=317598.

[HttpPost] [ValidateAntiForgeryToken] public async Task<ActionResult> Create( [Bind(Include = "EditoraId,Nome")] Editora editora) { try { var client = WebApiHttpClient.GetClient(); string editoraJSON = JsonConvert.SerializeObject(editora); HttpContent content = new StringContent(editoraJSON, System.Text.Encoding.Unicode, "application/json"); var response = await client.PostAsync("api/Editoras", content); if (response.IsSuccessStatusCode) { return RedirectToAction("Index"); } else { return Content("Ocorreu um erro: " + response.StatusCode); } } catch { return Content("Ocorreu um erro."); } }

3.4.6 Necessário instalar o package Nuget System.Net.Http.Formatting.Extension Bt. dir. do rato em cima do nome do projeto Visita > Manage Nuget Packages…

Search: System.Net.Http.Formatting.Extension Browse

Download, Install

Page 10: Aplicação ASP.NET MVC Cliente de Aplicação Web …mouta/ARQSI-2016-2017-1Sem/Asp.NET/Aplicac… · 2. Criar a Aplicação Asp.Net Web API 2 Visual Studio 2015 > File > New > Project…

3.4.7 Métodos Edit de EditorasController

Inicial:

// GET: Editoras/Edit/5 public async Task<ActionResult> Edit(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Editora editora = await db.Editoras.FindAsync(id); if (editora == null) { return HttpNotFound(); } return View(editora); } // POST: Editoras/Edit/5 // To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see http://go.microsoft.com/fwlink/?LinkId=317598.

[HttpPost] [ValidateAntiForgeryToken] public async Task<ActionResult> Edit( [Bind(Include = "EditoraId,Nome")] Editora editora) { if (ModelState.IsValid) { db.Entry(editora).State = EntityState.Modified; await db.SaveChangesAsync(); return RedirectToAction("Index"); } return View(editora); }

Alterar para:

// GET: Editoras/Edit/5 public async Task<ActionResult> Edit(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } var client = WebApiHttpClient.GetClient(); HttpResponseMessage response = await client.GetAsync("api/Editoras/" + id); if (response.IsSuccessStatusCode) { string content = await response.Content.ReadAsStringAsync(); var editora = JsonConvert.DeserializeObject<Editora>(content); if (editora == null) return HttpNotFound(); return View(editora); } return Content("Ocorreu um erro: " + response.StatusCode); } // POST: Editoras/Edit/5 // To protect from overposting attacks, please enable the specific properties you want to bind to, for

Page 11: Aplicação ASP.NET MVC Cliente de Aplicação Web …mouta/ARQSI-2016-2017-1Sem/Asp.NET/Aplicac… · 2. Criar a Aplicação Asp.Net Web API 2 Visual Studio 2015 > File > New > Project…

// more details see http://go.microsoft.com/fwlink/?LinkId=317598.

[HttpPost] [ValidateAntiForgeryToken] public async Task<ActionResult> Edit( [Bind(Include = "EditoraId,Nome")] Editora editora) { try { var client = WebApiHttpClient.GetClient(); string editoraJSON = JsonConvert.SerializeObject(editora); HttpContent content = new StringContent(editoraJSON, System.Text.Encoding.Unicode, "application/json"); var response = await client.PutAsync("api/Editoras/" + editora.EditoraId, content); if (response.IsSuccessStatusCode) { return RedirectToAction("Index"); } else { return Content("Ocorreu um erro: " + response.StatusCode); } } catch { return Content("Ocorreu um erro."); } }

3.4.8 Métodos Delete de EditorasController

Inicial:

// GET: Editoras/Delete/5 public async Task<ActionResult> Delete(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Editora editora = await db.Editoras.FindAsync(id); if (editora == null) { return HttpNotFound(); } return View(editora); } // POST: Editoras/Delete/5 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public async Task<ActionResult> DeleteConfirmed(int id) { Editora editora = await db.Editoras.FindAsync(id); db.Editoras.Remove(editora); await db.SaveChangesAsync(); return RedirectToAction("Index"); }

Page 12: Aplicação ASP.NET MVC Cliente de Aplicação Web …mouta/ARQSI-2016-2017-1Sem/Asp.NET/Aplicac… · 2. Criar a Aplicação Asp.Net Web API 2 Visual Studio 2015 > File > New > Project…

Alterar para: // GET: Editoras/Delete/5 public async Task<ActionResult> Delete(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } var client = WebApiHttpClient.GetClient(); HttpResponseMessage response = await client.GetAsync("api/Editoras/" + id); if (response.IsSuccessStatusCode) { string content = await response.Content.ReadAsStringAsync(); var editora = JsonConvert.DeserializeObject<Editora>(content); if (editora == null) return HttpNotFound(); return View(editora); } return Content("Ocorreu um erro: " + response.StatusCode); } // POST: Editoras/Delete/5 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public async Task<ActionResult> DeleteConfirmed(int id) { try { var client = WebApiHttpClient.GetClient(); var response = await client.DeleteAsync("api/Editoras/" + id); if (response.IsSuccessStatusCode) { return RedirectToAction("Index"); } else { return Content("Ocorreu um erro: " + response.StatusCode); } } catch { return Content("Ocorreu um erro."); } }

3.4.9 Método Dispose de EditorasController

//protected override void Dispose(bool disposing) //{ // if (disposing) // { // db.Dispose(); // } // base.Dispose(disposing); //}

Page 13: Aplicação ASP.NET MVC Cliente de Aplicação Web …mouta/ARQSI-2016-2017-1Sem/Asp.NET/Aplicac… · 2. Criar a Aplicação Asp.Net Web API 2 Visual Studio 2015 > File > New > Project…

4. Executar o Serviço e o Cliente

Executar a aplicação Web API (WebApiLivros).

Copiar o endereço base do serviço e colocar na classe helper WebApiHttpClient da aplicação Cliente MVC (ClienteMvcLivros).

Executar a aplicação Cliente MVC (ClienteMvcLivros).

Na barra de endereços do browser acrescentar /Editoras

Testar as várias ações do controlador Editoras.

5. Alterar a classe LivrosController

Alterar os métodos Index, Details, Create, Edit e Delete de um modo semelhante às alterações

na classe EditorasController.