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 algún 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.
HistorialDAOcspublic 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.Historialwhere historial.TablaId == tablaId&& historial.OrigenId == origenIdselect 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.
ActividadEnumeration.cspublic 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
BaseController.cspublic 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
ProductosController.cs[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
HistorialFilter.csusing 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étodopublic void OnActionExecuted(ActionExecutedContext context){bool correcto = false;//Si la acción se realiza correctamentecorrecto = context.Result is OkObjectResult|| context.Result is NoContentResult|| context.Result is CreatedAtActionResult;if (correcto){ClaimsPrincipal Usuario = context.HttpContext.User;//Obtenemos nuestro controladorvar 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//realizadaint 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 historialHistorialDAO 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 registroif (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.