using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.Data.SqlClient; using Microsoft.Extensions.Primitives; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Text.Json; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using MTWorkHR.Core.UnitOfWork; using MTWorkHR.Application.Services; using MTWorkHR.Core.Global; using Microsoft.Extensions.Logging; namespace MTWorkHR.Application.Middlewares { public class LoggingMiddleware { private readonly RequestDelegate _next; private readonly ILogger _logger; public LoggingMiddleware(RequestDelegate next, ILogger logger) { _next = next; _logger = logger; } public async Task Invoke(HttpContext context, IUnitOfWorkLog unitOfWork) { try { await _next(context); } catch (Exception error) { //Get target controller info _logger.LogError(error, "An error occurred during request processing"); var controllerActionDescriptor = context? .GetEndpoint()? .Metadata .GetMetadata(); //get controllerName & actionName var controllerName = controllerActionDescriptor?.ControllerName; var actionName = controllerActionDescriptor?.ActionName; //get QueryString var req = context?.Request; var QueryString = req?.QueryString.Value?.ToString(); // get request body string bodyStr; req.EnableBuffering(); req.Body.Seek(0, SeekOrigin.Begin); req.Body.Position = 0; using (StreamReader reader = new StreamReader(req.Body, Encoding.UTF8, true, 1024, true)) { bodyStr = await reader.ReadToEndAsync(); } //**Get Log service and entity info by refliction //Get target log entity by the traget controller name Type? entityType = Type.GetType("MTWorkHR.Core.Entities." + "User" + "Log, MTWorkHR.Core"); var logServiceWithGenericType = typeof(LogService<>).MakeGenericType(entityType); dynamic service = Activator.CreateInstance(logServiceWithGenericType, new object[] { unitOfWork }); var msg = error is AppException ? ((AppException)error).ErrorMessage : error.Message; var errorNum = error is AppException ? ((AppException)error).ErrorNumber : 0; // int errorNum = 0; // int.TryParse(errorNo, out errorNum); dynamic logEnitity = Activator.CreateInstance(entityType, new object[] { controllerName+"/"+actionName, QueryString, bodyStr, DateTime.Now, "",GetLocalIPAddress(), GetServerIp(context), GetUserExternalIp(context), "", "", msg, error?.InnerException?.Message }); //finally call service.create to insert the log await service.Create(logEnitity); //**** switch (error) { case AppException e: { context.Response.Clear(); context.Response.ContentType = "text/plain"; context.Response.StatusCode = StatusCodes.Status400BadRequest; await context.Response.WriteAsJsonAsync( new BadRequestResult { ErrorMsg = "" + ((AppException)error).ErrorMessage + "", ErrorNo = (int)errorNum }); return; } default: { context.Response.Clear(); context.Response.ContentType = "text/plain"; context.Response.StatusCode = StatusCodes.Status500InternalServerError; await context.Response.WriteAsync( "Internal Server Error" ); return; } } } } public static string GetServerIp(HttpContext context) { try { IPAddress ipAddressString = context.Connection.LocalIpAddress; string REMOTE_ADDR = context.GetServerVariable("REMOTE_ADDR"); string LOCAL_ADDR = context.GetServerVariable("LOCAL_ADDR"); string SERVER_ADDR = context.GetServerVariable("SERVER_ADDR"); string REMOTE_HOST = context.GetServerVariable("REMOTE_HOST"); string result = "LocalIpAddress: "+ipAddressString.ToString(); result += " REMOTE_ADDR: " + REMOTE_ADDR + " LOCAL_ADDR:" + LOCAL_ADDR + " SERVER_ADDR:" + SERVER_ADDR + " REMOTE_HOST:" + REMOTE_HOST; return result; } catch (Exception e) { return ""; } } public static string GetLocalIPAddress() { try { var host = Dns.GetHostEntry(Dns.GetHostName()); foreach (var ip in host.AddressList) { if (ip.AddressFamily == AddressFamily.InterNetwork) { return ip.ToString(); } } return ""; } catch (Exception e) { return ""; } } public static string GetUserExternalIp(HttpContext context) { try { IPAddress remoteIpAddress = context.Connection.RemoteIpAddress; string result = ""; if (remoteIpAddress != null) { // If we got an IPV6 address, then we need to ask the network for the IPV4 address // This usually only happens when the browser is on the same machine as the server. if (remoteIpAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) { remoteIpAddress = System.Net.Dns.GetHostEntry(remoteIpAddress).AddressList .First(x => x.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork); } result = remoteIpAddress.ToString(); } return result; } catch (Exception e) { return ""; } } } public class BadRequestResult { public string ErrorMsg { get; set; } public int ErrorNo { get; set; } } }