Puedes agregar otro action filter para ir registrando todos los cambios que realizan los usuarios al sistema. Vamos a registrar el usuario, la fecha en que se realiza el cambio, y un campo adicional para agregar opciones adicionales, como por ejemplo mostrar el valor anterior.
Agregamos nuestra clase HistorialDAO para registrar el historial de los usuarios. El método borrar va a borrar la información del historial del registro que se esta borrando.
Copy public class HistorialDAO
{
private readonly CaducaContext contexto;
private readonly LocService localizacion;
public HistorialDAO ( CaducaContext context , LocService locService)
{
this . contexto = context;
this . localizacion = locService;
}
public async Task < bool > AgregarAsync ( int usuarioId ,
int actividad ,
string nombreTabla ,
int origenId ,
string observaciones)
{
var tablaId = await ObtenerIdTablaAsync (nombreTabla);
Historial historial = new Historial
{
Actividad = actividad ,
FechaHora = DateTime . Now ,
Observa = observaciones ,
OrigenId = origenId ,
TablaId = tablaId ,
UsuarioId = usuarioId
};
contexto . Historial . Add (historial);
contexto . SaveChanges ();
return true ;
}
private async Task < int > ObtenerIdTablaAsync ( string nombreTabla)
{
Tabla tabla = await contexto . Tabla
. FirstOrDefaultAsync (e => e . Nombre == nombreTabla);
if (tabla == null )
{
return - 1 ;
}
return tabla . Id ;
}
public async Task < bool > BorraAsync ( string nombreTabla ,
int origenId)
{
var tablaId = await ObtenerIdTablaAsync (nombreTabla);
var consulta = await ( from historial in contexto . Historial
where historial . TablaId == tablaId
&& historial . OrigenId == origenId
select historial). ToListAsync ();
contexto . Historial . RemoveRange (consulta);
contexto . SaveChanges ();
return true ;
}
}
Agregamos una Enumeración ActividadEnumeration con los tipos de actividades que los usuarios pueden realizar.
Copy public enum ActividadEnumeration
{
Borrar = - 1 ,
Insertar = 1 ,
Modificar = 2 ,
Autorizar = 3 ,
Cancelar = 4
}
Para esto agregamos una propiedad llamada Id de tipo entero a nuestra clase BaseController, aqui vamos a agregar el Id de cada registro que se este actualizando
Copy public class BaseController : Controller
{
public int Id;
public string Observaciones;
}
En ProductosController a los métodos Post, Put y Delete vamos a agregar el Id del registro y agregamos nuestro filtro historial
Copy [ TypeFilter ( typeof ( HistorialFilter ))]
public class ProductosController : BaseController
{
[ HttpPost ]
public async Task < IActionResult > PostProducto (
[ FromBody ] Producto producto)
{
if ( !await productoDAO . AgregarAsync (producto))
{
return StatusCode ( productoDAO . customError . StatusCode ,
productoDAO . customError . Message );
}
Id = producto . Id ;
return CreatedAtAction ( "GetCategoria" ,
new { id = producto . Id } , producto);
}
[ HttpPut ( "{id}" )]
public async Task < IActionResult > PutProducto ([ FromRoute ] int id ,
[ FromBody ] Producto producto)
{
if ( ! ModelState . IsValid )
return BadRequest (ModelState);
if (id != producto . Id )
return BadRequest ();
if ( !await productoDAO . ModificarAsync (producto))
{
return StatusCode ( productoDAO . customError . StatusCode ,
productoDAO . customError . Message );
}
Id = producto . Id ;
return NoContent ();
}
[ HttpDelete ( "{id}" )]
public async Task < IActionResult > DeleteProducto ([ FromRoute ] int id)
{
if ( ! ModelState . IsValid )
return BadRequest (ModelState);
if ( !await productoDAO . BorraAsync (id))
{
return StatusCode ( productoDAO . customError . StatusCode ,
productoDAO . customError . Message );
}
Id = id;
return Ok ();
}
En nuestra carpeta Filters agregamos un nueva clase HistorialFilter
Copy using System ;
using System . Linq ;
using System . Security . Claims ;
using CaducaRest . Controllers ;
using CaducaRest . Core ;
using CaducaRest . DAO ;
using CaducaRest . Models ;
using CaducaRest . Resources ;
using Microsoft . AspNetCore . Mvc ;
using Microsoft . AspNetCore . Mvc . Filters ;
namespace CaducaRest . Filters ;
public class HistorialFilter : IActionFilter
{
private readonly LocService _localizer;
private readonly CaducaContext _context;
public HistorialFilter ( CaducaContext context ,
LocService localizer)
{
this . _localizer = localizer;
this . _context = context;
}
//Este método se ejecuta al terminar el código de cada
//método
public void OnActionExecuted ( ActionExecutedContext context)
{
bool correcto = false ;
//Si la acción se realiza correctamente
correcto = context . Result is OkObjectResult
|| context . Result is NoContentResult
|| context . Result is CreatedAtActionResult ;
if (correcto)
{
ClaimsPrincipal Usuario = context . HttpContext . User ;
//Obtenemos nuestro controlador
var controller = context . Controller as BaseController ;
//Obtenemos el método que se ejecutó (POST, PUT,
//DELETE, etc)
string metodo = controller . Request . Method . ToLower ();
//Identificamos de acuerdo al método la acción
//realizada
int actividad;
switch (metodo)
{
case "post" :
actividad = ( int ) ActividadEnumeration . Insertar ;
break ;
case "put" :
case "patch" :
actividad = ( int ) ActividadEnumeration . Modificar ;
break ;
case "delete" :
actividad = ( int ) ActividadEnumeration . Borrar ;
break ;
default :
actividad = 0 ;
break ;
}
int UsuarioId = 0 ;
if (correcto)
{
int . TryParse ( Usuario . Claims
. FirstOrDefault (x => x . Type == ClaimTypes . Sid )
. Value , out UsuarioId);
if (UsuarioId > 0 && controller . Id > 0 )
{
//Si es una acción de alta o edición
//agregamos un registro al historial
HistorialDAO historialDAO =
new HistorialDAO (_context , _localizer);
if (actividad > 0 )
_ = historialDAO . AgregarAsync (UsuarioId ,
actividad ,
controller . permiso . Tabla ,
controller . Id ,
controller . Observaciones ). Result ;
else
{
//Borramos el historial del registro
if (actividad < 0 )
_ = historialDAO
. BorraAsync ( controller . permiso . Tabla ,
controller . Id ). Result ;
}
}
}
}
}
public void OnActionExecuting ( ActionExecutingContext context)
{
}
}
De esta manera cada vez que se guarda, modifica, o borra algún registro guardamos el historial de cambios del registro.