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
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
Saber que version tienes .NetCore
Descargar .net Core
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ú
Abrir el terminal
Una vez que tengamos la carpeta, vamos a necesitar sacar una ventana de
Crear Proyecto de Consola
1. Crear la carpeta del Proyecto
2. Ir a la carpeta del Proyecto
3. Crear el Proyecto con
Ejecutar el proyecto
Comando: dotnet run
Comando
Habiltar la Depuración C# en Visual Studio Code
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
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
Agregar Referencia a Proyecto
Tutoriales .Net Core
https://dotnet.microsoft.com/learn
Ejecutar en una Terminal
dotnet new webApp -o myWebApp --no-https
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.
Crear Aplicaciones API
Web - Restful
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
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
➢
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.
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.
Model/Task
export class
Task {
id: number;
title: string;
description: string;
priority: boolean;
}
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(
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;
}
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));
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 ) {
}
}
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')) );
}
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'
,[]))
);
}
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
}
`
))
);
}
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'
))
);
}
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'
))
);
}
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
}
`
);
}
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
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] })
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"]'>
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>
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
<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>
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') });
}
}
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>
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(); }
}
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
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.
Organización de Proyecto DotNet
Angular
Crear Modelo de Task
▪
Crea un folder con el nombre
Models.
Models/Task.cs
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; }
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
using Microsoft.EntityFrameworkCore;
namespace TaskSharpHTTP.Models
{
public class TaskContext : DbContext
{
public TaskContext(DbContextOptions<TaskContext> options) :
base(options) {
}
public DbSet<TaskItem> TaskItems { get; set; }
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:
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
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]")] [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
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í
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(); }
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; }
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 .
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
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
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
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.
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
// 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 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();
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
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,
Páginas de ayuda de API
web de ASP.NET Core con
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
¿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
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
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
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
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:
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
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.
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’))