0% encontró este documento útil (0 votos)
6 vistas21 páginas

Progra IV

El documento detalla el proceso de configuración de una API en ASP.NET Core con Entity Framework para interactuar con una base de datos SQL Server, incluyendo la creación de modelos, controladores y la implementación de métodos CRUD. También se describe cómo desplegar la base de datos y la API en la nube, así como el consumo de la API desde un sitio web MVC. Finalmente, se menciona la implementación de autenticación mediante JWT y la creación de una tabla de usuarios para gestionar el acceso.

Cargado por

Oscar Alas
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
6 vistas21 páginas

Progra IV

El documento detalla el proceso de configuración de una API en ASP.NET Core con Entity Framework para interactuar con una base de datos SQL Server, incluyendo la creación de modelos, controladores y la implementación de métodos CRUD. También se describe cómo desplegar la base de datos y la API en la nube, así como el consumo de la API desde un sitio web MVC. Finalmente, se menciona la implementación de autenticación mediante JWT y la creación de una tabla de usuarios para gestionar el acceso.

Cargado por

Oscar Alas
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 21

-

Cambiar en SQL server click derecho en el servidor, propiedades, security, cambiar a SQL server
and Windows authentication mode , luego en el server/ security/logins ,verificar que este sa
(superusuario), si no está habilitado le damos click derecho/ propiedades /status/ enable, luego en
general darle una contraseña (en este caso la contraseña es Uh2024) y quitamos el check enforce
password policy.

En visual Studio abrimos el proyecto nuevo en este modo.


Crear 3 carpetas

Creamos clase en Models(en esta ocasión la llamamos Product) y agregamos los variables

[Key]// Hace el id como llave primaria

public int ID { get; set; }

public string Descripcion { get; set; }

public decimal PrecioCompra { get; set; }

public decimal Impuesto { get; set; }

public DateTime FechaRegistro { get; set; }

public char Estado { get; set; }

Despues

en el nombre de proyecto ponemos el primero dos datos en disable y segundo enable .


Seguidamente.

Creamos ORM ,en la raíz del programa click derecho//administrar paquetes NuGet.

damos en examinar y ponemos:

 entity framework core sql, seleccionamos el segundo e instalamos.


 entity framework core tools, seleccionamos el segundo e instalamos.

Esto para poder interactuar con la base de datos, los paquetes deben verse como la figura de
arriba.

Luego nos vamos a appsettings.json y creamos la cadena de conexion:

"ConnectionStrings": {

"StringConexion": "Server=DESKTOP-EA10T5P\\SQLEXPRESS;DataBase=DbProductos;user
id=sa;Password=Uh2024;TrustServerCertificate=True"

Ahora en la carpeta data creamos una clase (DbContextProducts)para la base de datos .

Le indicamos a la clase que va a usar el ORM haciendo referencia y utilizando

using Microsoft.EntityFrameworkCore; // de aqui sale la la referencia para por usar la librería


DbContext

using API_Products.Model; // da permisos de usar un objeto , en este caso de usar la clase


Products. Le heredamos DbContext a la clase

Luego en Program.cs abajo de builder.Services.AddControllers();

Colocamos:

Antes usamos la referencia en esa clase: using Microsoft.EntityFrameworkCore;

//Configuración del contexto se indicar el string de conexión que almacena la información del
servidor base datos,se configura el ORM para que trabaje con la clase DbContextProducts además
se indica el string de conexión que apunta al servidor SQL.

builder.Services.AddDbContext<API_Products.Data.DbContextProducts>(options =>

options.UseSqlServer(builder.Configuration.GetConnectionString("StringConexion")));
Tambien le indicamos que herede de la librería DbContext que se encarga de interactuar con el
server de base de datos

Seguimos en la clase de la carpeta Data

Creamos el constructor de la clase con el shortcut ctor

El parámetro de llama options , va a usar el constructor de la clase padre y le vas a enviar el


parámetro options.

Método encargado de crear el modelo en la base de datos

Ahora vamos a herramientas/ administrador de paquetes NuGet /consola de administrador de


paquetes. Agregamos :add-migration DbProductos

Luego: update-database.

Vamos a generar controlador en la carpeta controller /agregar controlador de MVC en blanco y le


ponemos ProductsController.cs y agregamos , ahí referenciamos la carpeta using
API_Products.Data y using API_Products.Model;
Y hacemos el código de

using Microsoft.AspNetCore.Mvc;

//referencia para la carpeta data


using API_Productos1.Data;
using API_Productos1.Model;
using API_Productos1.Data;

namespace API_Products.Controllers
{
public class ProductsController : Controller
{

//variable de tipo DbContext para utilizar la referencia del ORM y realizar


transacciones en la DB
private readonly DbContextProducts Context = null;

//El constructor con parámetros recibe la instancia del DbContext


public ProductsController(DbContextProducts dbContextProducts)
{
//se asigna la instancia
this.Context = dbContextProducts;
}
[HttpGet("Lista")]
public List<Productos> Lista()
{
List<Productos> lista = null;

lista = Context.Producto.ToList();

return lista;
}

[HttpPut("Registrar")]
public async Task<string> Registrar(Productos pProduct)
{
string mensaje = "";

try
{
Context.Producto.Add(pProduct);
await Context.SaveChangesAsync();
mensaje = "Producto registrado correctamente...";
}
catch (Exception ex)
{

mensaje = "No se logró guardar el producto.." + ex.InnerException;


}
return mensaje;
}

//Metodo encargado de buscar un producto en especifico


[HttpGet("Consultar")]
public Productos Buscar (int id)
{
//variable objeto para almacenar el producto
Productos temp = null;
// se retorna la informacion del producto
temp= Context.Producto.FirstOrDefault(x => x.ID == id);
return (temp == null ? new Productos() { ID = id, Descripcion = "No
Existe" }:temp) ;
}

//metodo para eliminar productos


[HttpDelete ("Eliminar")]
public String Eliminar (int id)
{
//almacena el texto del mensaje
string Mensaje = "";

//busca el producto a eliminar por medio del id


Productos temp =Context.Producto.FirstOrDefault(r=>r.ID == id);

//verifica si hay datos


if (temp != null)
{
//se elimina el producto en caso que exista
Context.Producto.Remove(temp);
//se aplica los cambios
Context.SaveChanges();

//se muestra el mensaje al usuario


Mensaje = $"Producto{temp.Descripcion} eliminado
correctamente...";
}
else
{
Mensaje = "No existe el producto a eliminar";
}

//retorna el mensaje
return Mensaje;

[HttpPost("Editar")]

//este metodo NO es sincronico


//public string Editar(Productos temp)
//{
// Context.Producto.Update(temp);
// Context.SaveChanges();
// return $"Producto {temp.Descripcion} modificado correctamente...";
//}

//este metodo es sincronico


public async Task<string> Editar (Productos temp)
{
var aux=Context.Producto.FirstOrDefault(j=> j.ID==temp.ID);

if (aux != null)
{
aux.Descripcion = temp.Descripcion;
aux.PrecioCompra=temp.PrecioCompra;
aux.Impuesto=temp.Impuesto;
Context.Producto.Update(aux);
await Context.SaveChangesAsync();
return $"Producto {aux.Descripcion} modificado correctamente...";
}

else
{
return $"Producto {temp.ID} no existe ...";
}

}
}
SUBIR BBDD A LA NUBE
Ahora vamos a sincronizar la API y la BBDD a la nube , creamos dos cuentas Microsoft ,una para la
base de datos y otra para la api, lo registramos en somee, y escogemos el free hosting

Una vez que ingresamos . en el menú izquierdo en My SQL/database /create batabase , llenamos
el registro seleccionamos la versión 2022 de SQL , Nos vamos a managment y hacemos backup de
nuestra base de datos, luego en somee en la parte de base de datos nos dirigimos a restore/upload
and restore y buscamos el backup file , en run script se pueden hacer pruebas para verificar la
funcionabilidad de la BBDD y en database details salen los datos requeridos como nombre de
servidpr en la nube usuario y password para conectar la base de datos nada mas cuando vamos a
conectar en managment studio darle la opción SQL server authentication , también hay que
cambiar los datos de la cadena de conexión en la API

Cuenta : [email protected]

Contraseña:oscarFLOR09852.$

SUBIR API A LA NUBE


una vez ya registrada la segunda cuenta Microsoft en el menú izquierdo websites/create
website y completamos el registro , una vez listo creamos los files de la API para subirlo a
la nube , nos vamos a la raíz del programa , click derecho/ publicar / carpeta y
seleccionados la ruta y aceptamos los archivos creados los comprimimos y eso lo subimos
a la nube en mi proyecto creado en file manager /upload archive /upload and extract ,
luego de esto el link para consumir la API desde Postman se encuentra en el apartado de
summary
Cuenta: [email protected]

Contraseña:oscarFLOR09852.$

CONSUMO DE API DESDE SITIO WEB MVC


Creamos un plantilla web MVC

En model creamos la clase Product

Y creamos las variables

public class Product

public int ID { get; set; }

public string Descripcion { get; set; }

public decimal PrecioCompra { get; set; }

public decimal Impuesto { get; set; }

public DateTime FechaRegistro { get; set; }

public char Estado { get; set; }

Creamos al proyecto una carpeta llamada Data y dentro de la carpeta creamos una clase para
invocar a la API web creada anteriormente . y creamos el código :

public HttpClient IniciarAPI()

var client = new HttpClient();

client.BaseAddress = new Uri("https://localhost:7174"); //esta es la url del API web creado antes

return client;

Creamos un controlador en blanco en Controllers

En dependencias del proyecto click derecho/administrar paquetes NuGet/examinar y buscamos el


paquete llamado newtonsoft.Json , instalamos.
Referenciamos .Models , .Json Y .Data

Public class ProductsController : Controller


{
//Variable permite manejar la referencia para el objeto client
private readonly HttpClient clientHttp = null;

//Variable permite manejar la referencia para usar la API


private readonly API_Web_Products api = null;

//Constructor por omision


public ProductsController()
{
//se instancia la API
this.api = new API_Web_Products();

//se inicializa la API


this.clientHttp = this.api.IniciarAPI();
}
[HttpGet]
public async Task<IActionResult> Index()
{
//Variable para almacenar el listado productos
List<Product> listado = new List<Product>();
//se consume el método listado publicado en la API
HttpResponseMessage respuesta = await
clientHttp.GetAsync("/Products/Lista");// mismo nombre que se le dio al
get en la API web

if (respuesta.IsSuccessStatusCode)
{
//Se lee los datos en formato JSON
var resultado =
respuesta.Content.ReadAsStringAsync().Result;
//se convierte los datos en una lista de productos
listado =
JsonConvert.DeserializeObject<List<Product>>(resultado);
}
//se envia la lista de productos al front.end
return View(listado);
}
}//cierre controller
} //cierre namespaces
En esta parte del código que escribimos arriba :
public async Task<IActionResult> Index()
en el index le damos clic derecho/agregar vista /vista de razor.

Nombre de vista : index, o depende con se llame la vista creada

Plantilla :list

Clase de modelo:Product //Para este caso, siempre escoger el modelo creado

Marcamos usar pagina de diseño, buscamos en los tres puntos , views/shared/layout y agregamos
y de ahí nos enviara al index

Depues vamos a la pagina Layout , en las etiquetas <ul> agregamos el <li>

<li class="nav-item">

<a class="nav-link text-dark" asp-controller="Products" asp-action="Index">Products</a>

</li>

Aho hay que agregar código a la API programada anteriormente para que el programa pueda
guardar datos , al inicio del controlador de la API agregamos las siguientes dos etiquetas:
//estas dos etiquetas se utilizan para poder indicar que nuestro
controlador implementa protocolo HHTP rest
[ApiController]
//nombre de controlador
[Route("[controller]")]

Creamos el código en el controlador para etiqueta registrar


[HttpGet]
public IActionResult Create()// recordar crear la vista razor
{
return View();
}

[HttpPost]
[ValidateAntiForgeryToken]//no permite tantos llamados al metodo para
evita spam
public async Task<IActionResult> Create([Bind] Product product)
{
var agregar =
clientHttp.PutAsJsonAsync<Product>("/Products/Registrar", product);
//se espera que finalice
await agregar;
//se almacena el resultado de la API
var resultado = agregar.Result;
//Se valida si la transaccion fue exitosa
if (resultado.IsSuccessStatusCode)
{
//se ubica el usuario dentro del listado productos
return RedirectToAction("Index");
}
else
{
//se almacena el error
TempData["ERROR"] = "ERROR,no se logro almacenar el producto";
return View(product);
}

}//cierre método

Con este no es necesario manipular la vista

Etiqueta eliminar
[HttpGet]
public async Task<IActionResult> Delete(int ID) // crear la vista razor
{ //variable temporal para almacenar datos del producto
Product temp = new Product();
//se utiliza el metodo de la API para buscar el producto
HttpResponseMessage buscar = await
clientHttp.GetAsync($"/Products/Consultar?id={ID}");

//se verifica si fue exitoso


if (buscar.IsSuccessStatusCode)
{ //se leen los datos en formato JSON
var resultado = buscar.Content.ReadAsStringAsync().Result;

//los datos se convieren en un objeto producto


temp=JsonConvert.DeserializeObject<Product>(resultado);

}
//se retorna la view con los datos del producto
return View(temp);

}
[HttpPost]
public async Task<IActionResult> Delete(int? ID)
{
HttpResponseMessage delete = await
clientHttp.DeleteAsync($"/Products/Eliminar?id={ID}");
if (delete.IsSuccessStatusCode)
{
return RedirectToAction("Index");
}
else
{
return View(ID);
}

En la vista index de Products editamos lo siguiente de eliminar al final:

@Html.ActionLink("Delete", "Delete", new { id=item.ID})

Etiqueta Modificar
[HttpGet]
public async Task<IActionResult> Edit(int id) // crear la vista razor
{ //variable temporal para almacenar datos del producto
Product temp = new Product();
//se utiliza el metodo de la API para buscar el producto
HttpResponseMessage buscar = await
clientHttp.GetAsync($"/Products/Consultar?id={ID}");

//se verifica si fue exitoso


if (buscar.IsSuccessStatusCode)
{ //se leen los datos en formato JSON
var resultado = buscar.Content.ReadAsStringAsync().Result;

//los datos se convieren en un objeto producto


temp=JsonConvert.DeserializeObject<Product>(resultado);

}
//se retorna la view con los datos del producto
return View(temp);

Y modificamos en el index :

@Html.ActionLink("Edit", "Edit", new { id=item.ID}) |

[HttpPost]
public async Task<IActionResult> Edit([Bind] Product temp)
{
HttpResponseMessage mensaje = await
clientHttp.PostAsJsonAsync<Product>("/Products/Editar", temp);
if (mensaje.IsSuccessStatusCode)
{
return RedirectToAction("Index");
}
else
{
return View(temp);
}

Etiqueta Details
public async Task<IActionResult> Details(int Id) // crear la vista
razor
{
Product temp = new Product();
HttpResponseMessage buscar = await
clientHttp.GetAsync($"/Products/Buscar?id={Id}");
if (buscar.IsSuccessStatusCode)
{
var resultado = buscar.Content.ReadAsStringAsync().Result;
temp = JsonConvert.DeserializeObject<Product>(resultado);

}
return View(temp);
}

Editamos el index details

@Html.ActionLink("Details", "Details", new { id=item.ID})

JWT JASON WEB TOKEN


Agregar dos paquetes NuGet en la API

JWT bearer 8.0.11

identity model toke 8.3.0

Ahora hay que crear una tabla de usuarios para autenticarnos

create table Usuarios(


Email varchar (100) not null primary key,
Password varchar (150) not null,
FechaRegistro datetime not null default getdate(),
Estado char not null default 'A')
GO
select * from Usuarios
go

insert into Usuarios (Email,Password) values ('[email protected]',


'123456')
go
insert into Usuarios (Email,Password) values ('[email protected]', '0985')
go

vamos a models y creamos una clase llamada Usuario

verificar que la librería using System.ComponentModel.DataAnnotations; este presente


[Key]
public string Email { get; set; }
public string Password { get; set; }
public DateTime FechaRegistro { get; set; }
public char Estado { get; set; }

agregamos una carpeta llamada Services al proyecto y ahí mismo agregamos una interfaz llamada
IAutorizacionServices.

Agregamos una clase llamada AutorizacionServices

En la interfaz colocamos
/// <summary>
/// metodo encargado de devolvcer el token al usuario autorizado
/// </summary>
/// <param name="autorizacion"></param>
/// <returns></returns>
Task< AutorizacionrResponse > DevolverToken(Usuario autorizacion);

En la clase heredamos : IAutorizacionServices


Da error le damos al bombillo y le damos crear interfaz y crea esto

public Task<AutorizacionResponse> DevolverToken(Usuario autorizacion)


{
throw new NotImplementedException();
}

AGREGAMOS LAS LIBRERIAS

using API_Productos1.Model;
//Librerias para implementar JWT
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
//para utilizar ORM
using Microsoft.EntityFrameworkCore;
using API_Productos1.Data;

ahora en la carpeta Data creamos otro DbSet para Usuarios y queda asi:
public DbSet <Usuario> Usuarios { get; set; }

regresamos a la clase AutorizacionServices y creamos el código :

using API_Productos1.Model;
//Librerias para implementar JWT
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
//para utilizar ORM
using Microsoft.EntityFrameworkCore;
using API_Productos1.Data;
using API_Productos1.Model.Custom;
namespace API_Productos1.Services
{
public class AutorizacionServices : IAutorizacionServices
{
//variable para usar la referencia del ORM
private readonly DbContextProducts _context;
//variable para utilizar el archivo de configuracion JSON
private readonly IConfiguration _configuration;

/// <summary>
/// constructor con parametros recibe la configuracion y
dbcontext
/// </summary>
/// <param name="configuration"></param>
/// <param name="context"></param>
public AutorizacionServices(IConfiguration
configuration ,DbContextProducts context)
{

this._configuration = configuration;
this._context = context;
}

public async Task<AutorizacionResponse> DevolverToken(Usuario


autorizacion)
{
var temp = await _context.Usuarios.FirstOrDefaultAsync(
x => x.Email.Equals(autorizacion.Email) &&
x.Password.Equals(autorizacion.Password));

if (temp == null)
{
//en caso de null regresa autorizacion en blanco
return await Task.FromResult<AutorizacionResponse>(null);

}
string tokenGenerado =
GenerarToken(autorizacion.Email.ToString());
return new AutorizacionResponse() { Token = tokenGenerado,
Resultado = true , Msj = "OK" };

private string GenerarToken(string IdUsuario)


{
//se lee la llave para henerar el token
var Key = _configuration.GetValue<string>("JwtSettings:Key");
//se convierte la key en un vector de bytes
var keyBytes =Encoding.ASCII.GetBytes(Key);

//se instancia la identidad que realiza el reclamo para la


autorizacion
var claims = new ClaimsIdentity();
//se agrega el identificador
claims.AddClaim(new Claim(ClaimTypes.NameIdentifier,
IdUsuario));

//credenciales del token


var credencialesToken = new SigningCredentials(
new SymmetricSecurityKey(keyBytes),
SecurityAlgorithms.HmacSha256Signature);

//se crea el descriptor del token


var tokenDescriptor = new SecurityTokenDescriptor
{
Subject=claims,
Expires=DateTime.UtcNow.AddMinutes(5),
SigningCredentials = credencialesToken
};

//se crea el encabezado para el token


var tokenHandler= new JwtSecurityTokenHandler();

//se crea el token


var tokenConfig= tokenHandler.CreateToken(tokenDescriptor);

//se escribe y almacena el token


var tokenCreado = tokenHandler.WriteToken(tokenConfig);

return tokenCreado;

}
}

vamos al código JSON y creamos el código después de la cadena de conexión


"JwtSettings": {

"key": "Frase_Jwt_palabra_key=*ProductsWebSeguridadUH"
}

Creamos una carpeta en Model llamada Custom y dentro de esta creamos una clase
llamada AutorizacionResponse y ahí agregamos el código :

public string Token { get; set; }


public string Resultado { get; set; }
public string Msj { get; set; }
vamos a program y agregamos después de la cadena de conexión

//configuracion del servicio JWT


//se agrega la interface y el objeto que la implementa

builder.Services.AddScoped<IAutorizacionServices, AutorizacionServices>();

//se toma la llave para el token


var key = builder.Configuration.GetValue<string>("JwtSettings:Key");
var keyBytes=Encoding.ASCII.GetBytes(key);

builder.Services.AddAuthentication(config =>
{
config.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
config.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
});

builder.Services.AddAuthentication(config =>
{
config.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
config.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(config =>
{
config.RequireHttpsMetadata = false;
config.SaveToken = true;
config.TokenValidationParameters = new
Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(keyBytes),
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero,

};

});

Agregamos un controlador encargado de manejar los usuarios UsuariosController

Y usamos las librerías

using API_Productos1.Services;
using API_Productos1.Data;
using Microsoft.AspNetCore.Mvc;
using API_Productos1.Services;
using API_Productos1.Data;
using Microsoft.EntityFrameworkCore;

namespace API_Productos1.Controllers
{
public class UsuariosController : Controller
{
//variable para manejar la referencia del ORM
private readonly DbContextProducts _context;
//variable para manejar el servicio de autorizacion
private readonly IAutorizacionServices _autorizacionServices;

public UsuariosController(DbContextProducts dbContext,


IAutorizacionServices autorizacionServices)
{
this._context = dbContext;
this._autorizacionServices = autorizacionServices;
}
[HttpPost]
[Route("AutenticarPW")]
public async Task<IActionResult> AutenticarPW(string email,string
password)
{

var temp = await _context.Usuarios.FirstOrDefaultAsync(


j => j.Email.Equals(email) &&
j.Password.Equals(password));

if (temp == null)
{

return Unauthorized ();//no autorizado


}
else
{

var autorizado = await


_autorizacionServices.DevolverToken(temp);

if (autorizado==null)
{
return Unauthorized();
}
else
{
return Ok(autorizado);//SE DEVUELVE EL TOKEN
}
}
}
}
}

También podría gustarte