PresentacionNetCoreAngular PDF
PresentacionNetCoreAngular PDF
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.
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
https://www.campusmvp.es/recursos/post/visual-studio-code-como-
preparar-un-entorno-de-trabajo-para-net-core.aspx
Saber que version tienes .NetCore
dotnet --version
Descargar .net Core
https://dotnet.microsoft.com/download
Extensiones
Instalando las extensiones necesarias
Crear un Proyecto de
Consola
Hola Mundo!
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ú File-
>Open Folder o con el acceso directo Ctrl+K,Ctrl+O (son dos combinaciones de
teclas, una después de la otra):
Abrir el terminal
Una vez que tengamos la carpeta, vamos a necesitar sacar una ventana de
terminal para lanzar comandos de compilación y similares. Para eso, dentro
del menú View, pulsamos sobre el botón Terminal o con el acceso directo
Ctrl+ñ:
Crear Proyecto de Consola
Comando
Commands Sln
https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-sln
Add/Remove project
https://dotnet.microsoft.com/learn
https://dotnet.microsoft.com/learn/web/aspnet-hello-world-tutorial/create
Ejecutar en una Terminal
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.
Esto se debe a que en el Proyecto existen dos modulos y es necesario establecer en cual de los dos se importaran
los components por este motive debe utilizer -–module=ap para indicar que se importarán en app.Module.tsque es
modulo por defecto de una aplicaicon angular.
Models/Task
Model/Task
export class Task {
id: number;
title: string;
description: string;
priority: boolean;
}
Imitar un Servidor Remoto con angular-in- InMemoryData
memory-web-api
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';
https://angular.io/tutorial/toh-pt5
Main.ts
Inspeccionando el Main.ts
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
const providers = [
{ provide: 'BASE_URL', useFactory: getBaseUrl, deps: [] }
];
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic(providers).bootstrapModule(AppModule)
.catch(err => console.log(err));
TaskService
TaskService
import { Injectable,Inject } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
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 )
{
}
}
TaskService
Metdod addTask - Agregar Task
Routing
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Nav-menu-component
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"]'>
<a class="nav-link text-dark" [routerLink]='["/tasklist"]'>Consultar Tareas</a>
</li>
</ul>
</div>
</div>
</nav>
TaskList
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);
}
}
Task-Add Component - Html TaskAdd
<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>
TaskAdd
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 {
add() {
this.taskService.addTask(this.task)
.subscribe(task => {
alert('Se agrego una nueva tarea')
});
}
}
TaskEdit
<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>
Task-Edit Component - ts TaskEdit
import { Component, OnInit } from get(): void {
'@angular/core'; const id =
import { ActivatedRoute } from +this.route.snapshot.paramMap.get('id');
'@angular/router';
import { TaskService } from
this.taskService.get(id)
'../services/task.service'; .subscribe(hero => this.task = hero);
import { Task } from '../models/task'; }
import { Location } from '@angular/common';
update(): void {
@Component({ this.taskService.update(this.task)
selector: 'app-task-edit', .subscribe(() => this.goBack());
templateUrl: './task-edit.component.html',
styleUrls: ['./task-edit.component.css']
}
})
export class TaskEditComponent implements delete(): void {
OnInit { this.taskService.delete(this.task)
.subscribe(() => this.goBack());
task:Task; }
stask:string;
constructor
(
goBack(): void {
private route: ActivatedRoute, this.location.back();
private taskService: TaskService, }
private location: Location }
) { }
ngOnInit() {
this.get();
}
Proyecto Core
▪ Crea una Clase con el nombre TaskItem en la carpeta Models haceindo click derecho
sobre la carpeta
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; }
}
}
Models/TaskContext.cs
{
public class TaskContext : DbContext
{
public TaskContext(DbContextOptions<TaskContext> options) :
base(options)
{
}
public DbSet<TaskItem> TaskItems { get; set; }
}
}
Startup.cs
// 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);
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ó.
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]")] Decorar la clase para que se comporte como una WebAPI
[ApiController]
public class TaskController : ControllerBase
{
private readonly TaskContext _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
}
}
El Atributo [HttpGet]: Routing and URL paths
El [HttpGet]atributo denota un método
que responde a una solicitud HTTP GET.
using Microsoft.AspNetCore.Mvc;
La ruta URL para cada método se
using
using
Microsoft.EntityFrameworkCore;
System.Collections.Generic;
construye de la siguiente manera:
using
using
System.Linq;
System.Threading.Tasks;
•Comience con la cadena de la plantilla
using TaskSharpHTTP.Models; en el atributo [Route] el controlador así
namespace TaskSharpHTTP.Controllers
{
GET:api/Task
[Route("api/[controller]")]
[ApiController]
public class TaskController : ControllerBase
{
private readonly TaskContext _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();
}
}
}
Metodo GetTaskItems Consultar varios
Items en la Clase TaskController
// GET: api/Task URL paths
[HttpGet]
public async Task<ActionResult<IEnumerable<TaskItem>>> GetTaskItems()
{
return await _context.TaskItems.ToListAsync();
}
Método GetTaskItem
Consultar un Item en la Clase TaskController
if (taskItem == null)
{
return NotFound();
}
return taskItem;
}
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 .
A continuación se presentan el código de los métodos.
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
respuesta que debe aparecer en su
navegador será la que se visualiza en la
imagen. En caso contrario ver la consola para
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
{"id":5,"title":"Priorizar el
proyecto","description":"Priorizar","priority":true}
Explicaión -Respuesta de la Ejecución
del método POST
// 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);
}
Método PUT: Modificar un TAskItem
// 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();
_context.TaskItems.Remove(TaskItem);
await _context.SaveChangesAsync();
return NoContent();
}
Páginas de ayuda de API
web de ASP.NET Core con
Swagger / OpenAPI
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
Core. Además, NSwag ofrece enfoques para generar código de cliente
de TypeScript y C # para su API.
¿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
cantidad de tiempo necesario para documentar con precisión un
servicio.
Especificación de Swagger (swagger.json)
https://medium.com/@davidjguru/single-
page-application-un-viaje-a-las-spa-a-
trav%C3%A9s-de-angular-y-javascript-
337a2d18532