• No se han encontrado resultados

PresentacionNetCoreAngular pdf

N/A
N/A
Protected

Academic year: 2020

Share "PresentacionNetCoreAngular pdf"

Copied!
92
0
0

Texto completo

(1)
(2)
(3)

Plataformas

 As you can see from the above diagram, the .NET ecosystem has three major

high-level components - .NET Framework, .NET Core, and Xamarin.

Xamarin is not a debate at all. When you want to build mobile (iOS, Android, and

Windows Mobile) apps using C#, Xamarin is your only choice.

The .NET Framework supports Windows and Web applications. Today, you can use

Windows Forms, WPF, and UWP to build Windows applications in .NET Framework. ASP.NET MVC is used to build Web applications in .NET Framework.

.NET Core is the new open-source and cross-platform framework to build

(4)

Referencias

https://www.c-sharpcorner.com/article/difference-between-net-framework-and-net-core/

 https://blogs.msdn.microsoft.com/dotnet/2016/07/15/net-core-roadmap/

https://docs.microsoft.com/en-us/dotnet/articles/standard/choosing-core-framework-server

 https://docs.microsoft.com/en-us/dotnet/articles/core/porting/index

 How to Select .NET Edition for your projects

(5)

Saber que version tienes .NetCore

(6)

Descargar .net Core

(7)
(8)
(9)
(10)

Creando una aplicación de consola .NET

Core en Visual Studio Code

 Crear una carpeta en la que queramos que esté el proyecto.

 Abrir la carpeta que se creó en Visual Studio Code utilizando el menú

(11)

Abrir el terminal

 Una vez que tengamos la carpeta, vamos a necesitar sacar una ventana de

(12)

Crear Proyecto de Consola

1. Crear la carpeta del Proyecto

2. Ir a la carpeta del Proyecto

3. Crear el Proyecto con

(13)
(14)

Ejecutar el proyecto

 Comando: dotnet run

Comando

(15)

Habiltar la Depuración C# en Visual Studio Code

(16)
(17)
(18)

Crear solución en visual studio Code

 Dentro de la carpeta donde vas a alojar la solucion

dotnet new sln

 La solución tendrá el nombre de la carpeta

Instalar la Extensión vscode-solution-explorer

fernandoescolar.vscode-solution-explorer

 Commands Sln

(19)

Add/Remove project

 dotnet sln [<SOLUTION_NAME>] add <PROJECT> <PROJECT> ... dotnet sln

[<SOLUTION_NAME>] add <GLOBBING_PATTERN>

 dotnet sln [<SOLUTION_NAME>] remove <PROJECT> <PROJECT> ... dotnet sln

(20)

Agregar Referencia a Proyecto

(21)
(22)

Tutoriales .Net Core

 https://dotnet.microsoft.com/learn

(23)

Ejecutar en una Terminal

 dotnet new webApp -o myWebApp --no-https

(24)

Crear una aplicación Web con Asp.net

Core

¿Qué significan estos comandos?

 El comando dotnet new crea una nueva aplicación.

 El parámetro webApp selecciona qué plantilla usar al crear su aplicación.

 El parámetro –o crea un directorio llamado myWebApp donde se almacena su aplicación.  La bandera --no-https especifica que no se habilite HTTPS.

 El cd my WebApp comando te coloca en el directorio de aplicaciones recién creado.

¿Qué archivos se crearon?

 Se crearon varios archivos en el myWebApp directorio, para brindarle una aplicación web

simple que está lista para ejecutarse.

 Startup.cs Contiene todos los ajustes y configuraciones.

(25)
(26)
(27)

Crear Aplicaciones API

Web - Restful

(28)

Crear Proyecto .Net Core y Angular

Para crear un proyecto con .Net Core y angular digite en

la terminal el siguiente commando

>dotnet new angular

Esta instrucción crear un Proyecto web Api configurado

con un Proyecto angular internamente

Si desea crear el Proyecto dentro de una carpeta ejecute

(29)

Actualizar angular a version actual

Es necesario actualizar el Proyecto de angular

Para debe ingresar en la carpeta con el Proyecto Angular

llamada ClientApp con la siguiente instruccion

> cd clientApp

Una vez se encuentre dentro de la carpeta ejecute la

siguiente instrucción para actualizer el Proyecto de

angular

>

ng update @angular/cli @angular/core

(30)

Si al ejecutar la instrucción de actualizacion de angular

siguen apareciendo

errores,

es posible que la actualización

de Angular no haya salido bien.

pruebe desinstalando angular

CLI y reinstalando con los

siguientes commandos e intente crear nuevamente el

servicio.

(31)

Taller Crear Aplicación Task para que

almacene en servidor

Comando Descripción

ng g class models/task Crear clase Task

ng generate service services/task Crear servicio para Task

ng g service services/inMemoryData Crear servicio para Manejar Http en Memoria ng g component taskAdd --module=app Crear componente para agregar task

ng g component taskList --module=app Crear componente para listar task ng g component taskEdit --module=app Crear componente para editar task

ClientApp

Nota: es possible que al crear los componenetes se presente el sigueinte error sino utiliza el -–module=app:

More than one module matches. Use skip-import option to skip importing the component into the closest module.

(32)

Model/Task

export class

Task {

id: number;

title: string;

description: string;

priority: boolean;

}

(33)

Imitar un Servidor Remoto con

angular-in-memory-web-api

InMemoryData

1. Instalar angular-in-memory-web-api

> npm install angular-in-memory-web-api --save

2. Importar el angular-in-memory-web-api en app.module.ts

import { HttpClientInMemoryWebApiModule } from 'angular-in-memory-web-api’;

import { InMemoryDataService } from './in-memory-data.service';

3. Agregar angular-in-memory-web-api al app.module.ts en el @ngModels en el array import

imports: [

BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }), HttpClientModule,

FormsModule,

RouterModule.forRoot([

{ path: '', component: HomeComponent, pathMatch: 'full' }, { path: 'counter', component: CounterComponent },

{ path: 'fetch-data', component: FetchDataComponent }, ]),

HttpClientModule,

HttpClientInMemoryWebApiModule.forRoot(

(34)

Crear la Service InMemoryDataService

InMemoryData

import { InMemoryDbService } from'angular-in-memory-web-api';

import { Task } from'../models/task'; @Injectable({

providedIn: 'root'

})

export classInMemoryDataServiceimplementsInMemoryDbService { createDb() {

const Task =[

{ id: 11, title: 'Crear Proyecto NetCore', description:'...', priority:true}, { id: 12, title: 'Ejecutar Proyecto', description:'...', priority:true},

{ id: 13, title: 'Probar Proyecto', description:'...', priority:false }, { id: 14, title: 'Depurar Proyecto', description:'...', priority:true} ];

return{Task}; }

// Overrides the genId method to ensure that a hero always has an id. // If the heroes array is empty,

// the method below returns the initial number (11).

// if the heroes array is not empty, the method below returns the highest // hero id + 1.

genId(tasks:Task[]):number{

returntasks.length> 0? Math.max(...tasks.map(task=> task.id)) + 1:11;

}

(35)

Inspeccionando el Main.ts

import { enableProdMode } from '@angular/core';

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';

import { environment } from './environments/environment';

export function getBaseUrl() {

return document.getElementsByTagName('base')[0].href; }

const providers = [

{ provide: 'BASE_URL', useFactory: getBaseUrl, deps: [] } ];

if (environment.production) { enableProdMode();

}

platformBrowserDynamic(providers).bootstrapModule(AppModule) .catch(err => console.log(err));

(36)

TaskService

import { Injectable,Inject } from '@angular/core';

import { HttpClient, HttpHeaders } from '@angular/common/http';

import { Observable, of, observable } from 'rxjs';

import { catchError, map, tap } from 'rxjs/operators';

import { Task} from '../models/task';

const httpOptions = {

headers: new HttpHeaders({ 'Content-Type': 'application/json' }) };

@Injectable({

providedIn: 'root'

})

export class TaskService {

constructor(private http:HttpClient, @Inject('BASE_URL') private baseUrl:string ) {

}

}

(37)

Metdod addTask - Agregar Task

/** POST: add a new task to the server */

addTask (task: Task): Observable<Task> {

return this.http.post<Task>(this.baseUrl+'api/task', task, httpOptions).pipe( tap((newTask: Task) => this.log(`added NewTask w/ id=${newTask.id}`)),

catchError(this.handleError<Task>('addTask')) );

}

(38)

getAl -Consultar todas las Task

/** GET Task from the server */

getAll():Observable<Task[]>

{

return

this

.http.get<Task[]>(

this

.baseUrl+

'api/Task'

).pipe(

tap(_

=>this

.log(

'Se Consulta la información'

)),

catchError(

this

.handleError<Task[]>(

'getAll'

,[]))

);

}

(39)

Consultar Task por Id- Consultar una Task

/** GET task by id. Will 404 if id not found */

get(id: number): Observable<Task>

{

const

url =

`

${this

.baseUrl +

'api/Task'

}

/

${

id

}

`

;

return this

.http.get<Task>(url).pipe(

tap(_

=> this

.log(

`fetched task id=

${

id

}

`

)),

catchError(

this

.handleError<Task>(

`getHero id=

${

id

}

`

))

);

}

(40)

Actualizar Task

/** PUT: update the Task on the server */

update (task: Task): Observable<any> {

const

url =

`

${this

.baseUrl +

'api/Task'

}

/

${

task.id

}

`

;

return this

.http.put(url, task, httpOptions).pipe(

tap(_

=> this

.log(

`updated task id=

${

task.id

}

`

)),

catchError(

this

.handleError<any>(

'task'

))

);

}

(41)

Eliminar Task

/** DELETE: delete the task from the server */

delete (task: Task | number): Observable<Task> {

const

id =

typeof

task ===

'number'

? task : task.id;

const

url =

`

${this

.baseUrl +

'api/Task'

}

/

${

id

}

`

;

return this

.http.delete<Task>(url, httpOptions).pipe(

tap(_

=> this

.log(

`deleted task id=

${

id

}

`

)),

catchError(

this

.handleError<Task>(

'deleteTask'

))

);

}

(42)

Manejo de Operaciones Http Fallidas en

el service

private

handleError<T> (operation =

'operation'

, result?: T) {

return

(error: any): Observable<T>

=>

{

console.error(error);

this

.log(

`

${

operation

}

failed:

${

error.message

}

`

);

return

of(result

as

T);

};

}

/** Log a HeroService message with the MessageService */

private

log(message: string) {

alert(

`TaskService:

${

message

}

`

);

}

(43)

Routing

Por convención, el nombre de la clase del módulo para

enrutado es AppRoutingModule y el archivo se crea en la

carpeta src/app/app-routing.module.ts. Ejecute el siguiente

comando en Angular CLI para crear el modulo.

> ng generate module app-routing --flat --module=app

(44)

Crear las rutas para el acceso a los componentes

creados

import { NgModule } from '@angular/core';

import { Routes, RouterModule } from '@angular/router';

import { TaskListComponent } from './task-list/task-list.component';

import { TaskAddComponent } from './task-add/task-add.component';

import { TaskEditComponent } from './task-edit/task-edit.component';

const routes: Routes = [

{

path:'tasklist',

component:TaskListComponent },

{

path:'taskadd',

component:TaskAddComponent },

{

path:'taskedit/:id',

component:TaskEditComponent } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] })

(45)

Agregar las rutas creadas al Menu del Proyecto en

Nav-menu-component

<header>

<nav class='navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3'> <div class="container">

<a class="navbar-brand" [routerLink]='["/"]'>TaskSharpHTTP</a>

<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-label="Toggle navigation" [attr.aria-expanded]="isExpanded" (click)="toggle()">

<span class="navbar-toggler-icon"></span> </button>

<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse" [ngClass]='{"show": isExpanded}'> <ul class="navbar-nav flex-grow">

<li class="nav-item" [routerLinkActive]='["link-active"]' [routerLinkActiveOptions]='{ exact: true }'> <a class="nav-link text-dark" [routerLink]='["/"]'>Home</a>

</li>

<li class="nav-item" [routerLinkActive]='["link-active"]'>

<a class="nav-link text-dark" [routerLink]='["/counter"]'>Counter</a> </li>

<li class="nav-item" [routerLinkActive]='["link-active"]'>

<a class="nav-link text-dark" [routerLink]='["/fetch-data"]'>Fetch data</a> </li>

<li class="nav-item" [routerLinkActive]='["link-active"]'>

<a class="nav-link text-dark" [routerLink]='["/taskadd"]'>AddTask</a> </li>

<li class="nav-item" [routerLinkActive]='["link-active"]'>

(46)

Task-List Component - Html

<div >

<h1 class="h2">List</h1> </div>

<div>

<table class='table table-striped'> <thead>

<tr> <tr>

<th>Id</th> <th>Titulo</th> <th>Descripción</th> <th>Prioridad</th> <th>Ver</th>

</tr> </thead>

<tr *ngFor="let task of tasks"> <td>{{task.id}}</td>

<td>{{task.title}}</td> <td>{{task.description}}</td>

<td><span *ngIf="task.priority===true;"> <b>Prioritario</b> </span></td> <td><a routerLink="/taskedit/{{task.id}}">ver</a></td>

</tr> </table> </div>

(47)

Task-List Component - ts

import { Component, OnInit } from '@angular/core';

import {TaskService} from '../services/task.service'

import { Task } from '../models/task';

import { getAllDebugNodes } from '@angular/core/src/debug/debug_node';

@Component({

selector: 'app-task-list',

templateUrl: './task-list.component.html', styleUrls: ['./task-list.component.css'] })

export class TaskListComponent implements OnInit {

tasks:Task[];

constructor(private taskservice:TaskService)

{ }

ngOnInit() {

this.getAll(); }

getAll(){

this.taskservice.getAll().subscribe(tasks=>this.tasks=tasks); }

}

(48)

Task-Add Component - Html

<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"> <h1 class="h2">Task Add </h1>

</div>

<p>Aplicación para agregar Task</p>

<div class="form-group"> <label>Id:

<input [(ngModel)]="task.id" class="form-control" placeholder="digite el id" type=“number"/> </label>

</div>

<div class="form-group"> <label>Titulo:

<input [(ngModel)]="task.title" class="form-control" placeholder="digite titulo" type="text"/> </label>

</div>

<div class="form-group"> <label>Descripción:

<input [(ngModel)]="task.description" class="form-control" placeholder="digite descripción " type="text" /> </label>

</div>

<div class="form-group"> <label>Prioritario:

<input type="checkbox" class="form-control" [(ngModel)]="task.priority"> </label>

</div>

<div class="form-group">

<button (click)="add()" class="btn btn-primary">Agregar</button> </div>

(49)

Task-Add Component - ts

import { Component, OnInit } from '@angular/core';

import { TaskService } from '../services/task.service';

import { Task } from '../models/task';

@Component({

selector: 'app-task-add',

templateUrl: './task-add.component.html', styleUrls: ['./task-add.component.css'] })

export class TaskAddComponent implements OnInit {

constructor(private taskService: TaskService) { } task: Task;

ngOnInit() {

this.task = { id: 0, title: '', description: '', priority: false }; }

add() {

this.taskService.addTask(this.task) .subscribe(task => {

alert('Se agrego una nueva tarea') });

}

}

(50)

Task-Edit Component - Html

<div *ngIf="task"> <div >

<h1 class="h2">Detalle Task</h1> </div>

<p>Editar/Eliminar Tareas</p> <div class="form-group"> <label>Id:

{{task.id}} </label> </div>

<div class="form-group"> <label>Titulo:

<input [(ngModel)]="task.title" class="form-control" placeholder="digite titulo" type="text"/> </label>

</div>

<div class="form-group"> <label>Descripción:

<input [(ngModel)]="task.description" class="form-control" placeholder="digite descripción " type="text" /> </label>

</div>

<div class="form-group"> <label>Prioritario:

<input type="checkbox" class="form-control" [(ngModel)]="task.priority"> </label>

</div>

<div class="form-group">

<button (click)="update()" class="btn btn-primary">Actualizar</button> <button (click)="delete()" class="btn btn-primary">Eliminar</button> </div>

</div>

(51)

Task-Edit Component - ts

import { Component, OnInit } from

'@angular/core';

import { ActivatedRoute } from

'@angular/router';

import { TaskService } from

'../services/task.service';

import { Task } from '../models/task';

import { Location } from '@angular/common';

@Component({

selector: 'app-task-edit',

templateUrl: './task-edit.component.html', styleUrls: ['./task-edit.component.css'] })

export class TaskEditComponent implements

OnInit {

task:Task; stask:string;

constructor

(

private route: ActivatedRoute,

private taskService: TaskService,

private location: Location ) { }

ngOnInit() {

this.get(); }

get(): void {

const id =

+this.route.snapshot.paramMap.get('id');

this.taskService.get(id)

.subscribe(hero => this.task = hero); }

update(): void {

this.taskService.update(this.task) .subscribe(() => this.goBack()); }

delete(): void {

this.taskService.delete(this.task) .subscribe(() => this.goBack()); }

goBack(): void {

this.location.back(); }

}

(52)

BackEnd DotNet Core

2.2

C#, WebApi, EntityFrameworkCore, InMemory, SqlServer, Test Api con PostMan, OpenApi Swagger

https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-web-api?view=aspnetcore-2.2&tabs=visual-studio#routing-and-url-paths

(53)

Proyecto .Net Core con Angular

 Crear el modelo de la clase.

 Crear el context de la base de Datos DBcontext.

 Register el context de la base .

 Crear el controlador.

 Agregar los metodos CRUD al Controlador.

 Configurar routing y URL paths.

 Especificar los valores de retorno.

(54)
(55)
(56)

Organización de Proyecto DotNet

Angular

(57)

Crear Modelo de Task

Crea un folder con el nombre

Models.

Models/Task.cs

(58)

using Newtonsoft.Json;

///<Summary>

/// Se coloca TaskItem a la Clase en lugar de Task, porque Task es una palabra Reservada de .NetCore

/// </Summary>

///

namespace TaskSharpHTTP.Models {

public class TaskItem {

[JsonProperty("id")]

public int Id { get; set; }

[JsonProperty("title")]

public string Title { get; set; }

[JsonProperty("description")]

public string Description { get; set; }

[JsonProperty("priority")]

public bool Priority { get; set; }

(59)

Contexto de Datos para Task

 El contexto de la Base de Datos es la clase principal que coordina las

funcionalidades del Entity Framework para los modelos de dato. Esta clase es una clase derivada de la clase

Microsoft.EntityFrameworkCore.DbContext class.

 En el folder Models crea una nueva calse con el nombre TaskContext

(60)

using Microsoft.EntityFrameworkCore;

namespace TaskSharpHTTP.Models

{

public class TaskContext : DbContext

{

public TaskContext(DbContextOptions<TaskContext> options) :

base(options) {

}

public DbSet<TaskItem> TaskItems { get; set; }

(61)

Register the database context

 En ASP.NET Core, el servicios DBContext debe registrarse en el contenedor de

inyección de dependencias (DI).

 El contenedor proporciona el servicio a los controladores.

 Actualice Startup.cs con el siguiente código resaltado:

(62)

lusing Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SpaServices.AngularCli; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.EntityFrameworkCore; using TaskSharpHTTP.Models; namespace TaskSharpHTTP {

public class Startup {

public Startup(IConfiguration configuration) {

Configuration = configuration; }

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services)

{

services.AddDbContext<TaskContext>(opt => opt.UseInMemoryDatabase("TaskBD"));

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); // In production, the Angular files will be served from this directory services.AddSpaStaticFiles(configuration =>

{

configuration.RootPath = "ClientApp/dist"; });

}

Este es el nombre que se encuentra en el Namespace de la Clase

(63)

Crear Controllers/TaskController.cs

 En la carpeta Controller del Proyecto crear la clase TaskController.cs

 colocar el decorador [ApiController] Con el fin de que la clase se comporte como una

WebAPI y responda ante solicitude HTTP.

 Colocar el atributo decorador [Route("api/[controller]")], una clase Controlador con el

atributo [ApiController] debe utilizar obligatoriamente el atributo de enrutado para acceder a las acciones de HTTP a través de las rutas, por lo que se debe adicionar el atributo

Inyectar el Contexto de la base de datos ( TaskContext) en el controlador Inyeccion de

Dependencia.

 Utilizar el contexto para cada uno de los métodos guardar consultar, actualizar y

eliminar (CRUD) (Create, Read, Uptate, Delete).

 Se debe agregar un ítem a la base de Datos para inicializarla a fin de que no este

vacia. Este código está en el constructor, por lo que se ejecuta cada vez que hay una nueva solicitud HTTP y solo en el caso en el que no hayan ítems.

 Si elimina todos los elementos, el constructor volverá a crear un item la próxima vez

que se llame a un método API, Por lo tanto, puede parecer que la eliminación no funcionó cuando realmente funcionó.

(64)

using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using TaskSharpHTTP.Models; namespace TaskSharpHTTP.Controllers {

[Route("api/[controller]")] [ApiController]

public class TaskController : ControllerBase

{

private readonly TaskContext _context;

public TaskController(TaskContext context) {

_context = context;

if (_context.TaskItems.Count() == 0) {

// Crea un nuevo item si la coleccion esta vacia,

// lo que significa que no puedes borrar todos los Items.

_context.TaskItems.Add(new TaskItem { Id = 1, Title = "Priorizar el proyecto", Description = "Priorizar", Priority = true }); _context.TaskItems.Add(new TaskItem { Id = 2, Title = "Calendario el proyecto", Description = "Priorizar", Priority = true });

_context.SaveChanges(); }

}

// Aquí, despues del constructor de la clase, irán los Métodos HTTP GET,POST, DELETE, PUT

} }

Inyeccion del TaskContext

(65)

El Atributo [HttpGet]: Routing and URL paths

using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using TaskSharpHTTP.Models; namespace TaskSharpHTTP.Controllers {

[Route("api/[controller]")] [ApiController]

public class TaskController : ControllerBase

{

private readonly TaskContext _context;

public TaskController(TaskContext context) {

_context = context;

if (_context.TaskItems.Count() == 0) {

// Crea un nuevo item si la coleccion esta vacia,

// lo que significa que no puedes borrar todos los Items.

_context.TaskItems.Add(new TaskItem { Id = 1, Title = "Priorizar el proyecto", Description = "Priorizar", Priority = true }); _context.TaskItems.Add(new TaskItem { Id = 2, Title = "Calendario el proyecto", Description = "Priorizar", Priority = true }); _context.SaveChanges();

} }

// GET: api/Task [HttpGet]

public async Task<ActionResult<IEnumerable<TaskItem>>> GetTaskItems() {

return await _context.TaskItems.ToListAsync(); }

} }

El [HttpGet]atributo denota un método que responde a una solicitud HTTP GET. La ruta URL para cada método se

construye de la siguiente manera:

•Comience con la cadena de la plantilla en el atributo [Route] el controlador así

(66)

Metodo GetTaskItems Consultar varios

Items en la Clase TaskController

// GET: api/Task

[HttpGet]

public async Task<ActionResult<IEnumerable<TaskItem>>> GetTaskItems() {

return await _context.TaskItems.ToListAsync(); }

(67)

Método GetTaskItem

Consultar un Item en la Clase TaskController

// GET: api/Task/5

[HttpGet("{id}")]

public async Task<ActionResult<TaskItem>> GetTaskItem(int id) {

var taskItem = await _context.TaskItems.FindAsync(id);

if (taskItem == null) {

return NotFound(); }

return taskItem; }

(68)

Explicación valor de retorno

ActionResult<T>

del método GET:

para Consulta de Datos en TaskController

Los métodos GetTaskItems(consultar todas las tareas) y

GetTaskitem(Consultar una tarea por Id) retornan un objeto

de

tipo

ActionResult<T>

Este

tipo

de

objeto

serializa(convierte) automáticamente el

objeto a JSON

y

escribe el JSON en el cuerpo del mensaje de respuesta.

El código de respuesta para este tipo de devolución es

200 si no hay excepciones

5xx si hay excepciones.

404 NotFound Si ningún elemento coincide con la ID

solicitada, el método devuelve un código de error .

(69)

Comó utilizar los Métodos GET

Los métodos implementan dos EndPoint o

Puntos Finales GET:

GET /api/task

GET /api/task/{id}

Ejecute la aplicación con

dotnet run

y

pruebe llamando a los dos EndPoint desde un

navegador. Por ejemplo:

https://localhost:<port>/api/task

https://localhost:<port>/api/task/1

Sino hay error al consultar los TaskItems la

(70)

Probar método Get con POSTMAN

1. Instalar Postman

2. Ejecutarsu aplicación web con dotnet run. 3. Deshabilitar la verificación del certificado SSL

 Desde Archivo> Configuración (pestaña General ),  desactive la verificación del certificado SSL .

Advertencia: Vuelva a habilitar la verificación del certificado SSL después de probar el controlador.

4. Crear una nueva solicitud Request en Postman. 1. Establezca el método HTTP en GET .

2. Establezca la URL de solicitud

en https://localhost:<port>/api/task.

Por ejemplo: https://localhost:5001/api/task

(71)

Método POST:Agregar un nuevo

TaskItems

// POST: api/Task

[HttpPost]

public async Task<ActionResult<TaskItem>> PostTaskItem(TaskItem item) {

_context.TaskItems.Add(item);

await _context.SaveChangesAsync();

return CreatedAtAction(nameof(GetTaskItem), new { id = item.Id }, item);

}

Recibe un Taskitem

Adiciona un Taskitem al DbSet creado en el TAskContext

(72)

Explicaión de la Ejecución del método

POST y la respuesta enviada.

 El código anterior es un método HTTP POST, como lo indica

el atributo [HttpPost] .

 El método recibe un TaskItem del cuerpo de la solicitud HTTP.

 El método CreatedAtAction: Debería devolver un código de estado HTTP 201, si

tiene éxito.

HTTP 201 es la respuesta estándar para un método HTTP POST que crea un nuevo recurso en el servidor.

 Una vez creado el TAskItems, se agrega un Location al encabezado a la respuesta

HTTP, el location especifica a la URI que la tarea ha sido creada.

 Para crear el Location en el encabezado de la Respuesta HTTP se debe hacer

referencia al método que consulta un taskItem para este caso es GetTaskItem.

(73)

Como Probar Método POST con Postman

1. Ejecutar el proyecto con dotnet run

2. En Postman, establece el método HTTP en POST.

3. Escriba la URL de la API https://localhost:5001/api/task

4. Seleccione la pestañaBody .

5. Seleccione el botón de radio en raw .

6. Establezca el tipo en JSON (application / json). 7. En el body del request, ingrese el siguiente JSON :

{"id":5,"title":"Priorizar el

(74)

// POST: api/Task

[HttpPost]

public async Task<ActionResult<TaskItem>> PostTaskItem(TaskItem item) {

_context.TaskItems.Add(item); await _context.SaveChangesAsync();

return CreatedAtAction(nameof(GetTaskItem), new { id = item.Id }, item); }

(75)

Método PUT: Modificar un TAskItem

Put Es similar a Post, excepto que

utiliza HTTP PUT. La respuesta es 204

(sin contenido) .

De acuerdo con la especificación

HTTP, una solicitud PUT requiere que

el cliente envíe toda la entidad

actualizada, no solo los cambios.

// PUT: api/Task/5

[HttpPut("{id}")]

public async Task<IActionResult> PutTaskItem(int id, TaskItem item)

{

if (id != item.Id) {

return BadRequest();

}

_context.Entry(item).State = EntityState.Modified;

await _context.SaveChangesAsync();

return NoContent();

(76)

Probar el método PUT

 Este ejemplo utiliza una base de

datos en memoria que debe iniciarse cada vez que se inicia la aplicación.

 Debe haber un elemento en la base

de datos antes de realizar una llamada PUT.

 Llame a GET para asegurarse de que

haya un elemento en la base de datos antes de hacer una llamada PUT.

 Actualice el elemento TaskItems que

tiene id = 1 y establezca su nombre

(77)
(78)

Método DELETE

// DELETE: api/Todo/5

[HttpDelete("{id}")]

public async Task<IActionResult> DeleteTaskItem(int id) {

var TaskItem = await

_context.TaskItems.FindAsync(id);

if (TaskItem == null) { return NotFound(); } _context.TaskItems.Remove(TaskItem); await _context.SaveChangesAsync(); return NoContent(); }

 Utilice el método DELETE en PostMan para

eliminar un TaskItem pendiente:

 Establece el método a DELETE.

 Establece el URI del objeto a eliminar, por

ejemplo https://localhost:5001/api/todo/1

 Seleccione Enviar

 La aplicación de ejemplo le permite eliminar

todos los elementos.

 Pero cuando el último elemento se elimina,

(79)
(80)

Páginas de ayuda de API

web de ASP.NET Core con

(81)

Swagger / OpenAPI

Al consumir una API web, comprender sus diversos métodos puede ser

un desafío para un desarrollador.

Swagger

, también conocido

como

OpenAPI

, resuelve el problema de generar documentación útil y

páginas de ayuda para las API web. Proporciona beneficios tales como

documentación interactiva, generación de SDK de cliente y

descubrimiento de API.

Swashbuckle.AspNetCore

es un proyecto de código abierto para

generar documentos Swagger para las API web principales de ASP.NET.

NSwag

es otro proyecto de código abierto para generar documentos

Swagger e integrar

Swagger UI

o

ReDoc

en las API web de ASP.NET

(82)

¿Qué es Swagger / OpenAPI?

Swagger es una especificación independiente del lenguaje para

describir las API

REST

.

El proyecto Swagger fue donado a

OpenAPI Initiative

, por lo

que ahora se conoce como OpenAPI.

Ambos nombres se usan indistintamente; sin embargo, se

prefiere OpenAPI.

OpenAPI Permite que tanto las computadoras como las personas

comprendan las capacidades de un servicio sin acceso directo a

la implementación (código fuente, acceso a la red,

documentación).

Un objetivo es minimizar la cantidad de trabajo necesario para

conectar servicios no asociados. Otro objetivo es reducir la

(83)

Especificación de Swagger (swagger.json)

El núcleo del flujo de Swagger es la especificación de Swagger: de

forma predeterminada, un documento llamado

swagger.json

.

Es generado por la cadena de herramientas Swagger (o

implementaciones de terceros) basadas en su servicio.

Describe las capacidades de su API y cómo acceder a ella con HTTP.

Controla la interfaz de usuario de Swagger y es utilizada por la cadena

de herramientas para habilitar el descubrimiento y la generación de

código de cliente.

Aquí hay un ejemplo de una especificación Swagger, reducida por

(84)
(85)

Swagger UI

 Swagger UI ofrece una interfaz de

usuario basada en la web que proporciona información sobre el servicio, utilizando la especificación Swagger generada.

 Tanto Swashbuckle como NSwag

(86)

Comience con NSwag y ASP.NET Core

 NSwag ofrece las siguientes capacidades:

 La capacidad de utilizar la interfaz de usuario Swagger y el generador de

Swagger.

 Capacidades flexibles de generación de código.

 Con NSwag, no necesita una API existente; puede usar API de terceros que

(87)

Registrar el middleware NSwag

 Registre el middleware NSwag para:

 Genere la especificación Swagger para la API web implementada.

 Sirve la interfaz de usuario de Swagger para explorar y probar la API web.

 Para usar el middleware NSwag ASP.NET Core, instale

el paquete NSwag.AspNetCore NuGet. Este paquete contiene el middleware para generar y servir la especificación Swagger, la interfaz de usuario Swagger (v2 y v3) y la interfaz de usuario ReDoc .

 Utilice el siguiente métodos para instalar el paquete NSwag NuGet:

(88)
(89)
(90)

API de información y descripción

En el Startup.ConfigureServices, una acción de configuración pasada al

AddSwaggerDocument agrega información como el autor, la licencia y la

(91)

Generación de Código

 Puede aprovechar las capacidades de generación de código de NSwag

eligiendo una de las siguientes opciones:

 NSwagStudio : una aplicación de escritorio de Windows para generar código

de cliente API en C # o TypeScript.

 Los paquetes

NSwag.CodeGeneration.CSharp o NSwag.CodeGeneration.TypeScript de NuGet

para la generación de código dentro de su proyecto.

 NSwag desde la línea de comandos .

 El paquete NSwag.MSBuild NuGet.

(92)

Tema Link

Conceptos de SPA https://medium.com/@davidjguru/single-page-application-un-viaje-a-las-spa-a-trav

https://medium.com/@davidjguru/single- page-application-un-viaje-a-las-spa-a- trav%C3%A9s-de-angular-y-javascript-337a2d18532

SignalR Angular Tutorial Viejo

https://codingblast.com/asp-net-core-signalr-chat-angular/

Tutorial Nuevo

https://code-maze.com/netcore-signalr-angular/

npm install @aspnet/signalr

Install Choco en Windows y nswagstudio Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object

System.Net.WebClient).DownloadString('h ttps://chocolatey.org/install.ps1’))

Referencias

Documento similar

The 'On-boarding of users to Substance, Product, Organisation and Referentials (SPOR) data services' document must be considered the reference guidance, as this document includes the

In medicinal products containing more than one manufactured item (e.g., contraceptive having different strengths and fixed dose combination as part of the same medicinal

Products Management Services (PMS) - Implementation of International Organization for Standardization (ISO) standards for the identification of medicinal products (IDMP) in

Products Management Services (PMS) - Implementation of International Organization for Standardization (ISO) standards for the identification of medicinal products (IDMP) in

This section provides guidance with examples on encoding medicinal product packaging information, together with the relationship between Pack Size, Package Item (container)

Package Item (Container) Type : Vial (100000073563) Quantity Operator: equal to (100000000049) Package Item (Container) Quantity : 1 Material : Glass type I (200000003204)

De acuerdo con Harold Bloom en The Anxiety of Influence (1973), el Libro de buen amor reescribe (y modifica) el Pamphihis, pero el Pamphilus era también una reescritura y

De hecho, este sometimiento periódico al voto, esta decisión periódica de los electores sobre la gestión ha sido uno de los componentes teóricos más interesantes de la