GlobalExceptionMiddleware.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. using Attribute;
  2. using Common;
  3. using Extensions;
  4. using Infrastructure;
  5. using Infrastructure.Model;
  6. using IPTools.Core;
  7. using Microsoft.AspNetCore.Http.Features;
  8. using Model;
  9. using NLog;
  10. using Services;
  11. using System.Text.Encodings.Web;
  12. using textJson = System.Text.Json;
  13. namespace Middleware
  14. {
  15. /// <summary>
  16. /// 全局异常处理中间件
  17. /// 调用 app.UseMiddlewareGlobalExceptionMiddleware>();
  18. /// </summary>
  19. public class GlobalExceptionMiddleware
  20. {
  21. private readonly RequestDelegate next;
  22. // private readonly ISysOperLogService SysOperLogService;
  23. static readonly Logger Logger = LogManager.GetCurrentClassLogger();
  24. public GlobalExceptionMiddleware(RequestDelegate next)
  25. {
  26. this.next = next;
  27. // this.SysOperLogService = sysOperLog;
  28. }
  29. public async Task Invoke(HttpContext context)
  30. {
  31. try
  32. {
  33. // 设置允许跨域的域名、方法等
  34. context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
  35. context.Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
  36. context.Response.Headers.Add("Access-Control-Allow-Headers", "DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization");
  37. // 如果请求方法是预检请求(OPTIONS),则直接返回成功状态码
  38. if (context.Request.Method == "OPTIONS")
  39. {
  40. context.Response.StatusCode = 200;
  41. await context.Response.WriteAsync("OK");
  42. return;
  43. }
  44. await next(context);
  45. }
  46. catch (Exception ex)
  47. {
  48. await HandleExceptionAsync(context, ex);
  49. }
  50. }
  51. private async Task HandleExceptionAsync(HttpContext context, Exception ex)
  52. {
  53. NLog.LogLevel logLevel = NLog.LogLevel.Info;
  54. int code = (int)ResultCode.GLOBAL_ERROR;
  55. string msg;
  56. string error = string.Empty;
  57. bool notice = true;
  58. //自定义异常
  59. if (ex is CustomException customException)
  60. {
  61. code = customException.Code;
  62. msg = customException.Message;
  63. error = customException.LogMsg;
  64. notice = customException.Notice;
  65. }
  66. else if (ex is ArgumentException)//参数异常
  67. {
  68. code = (int)ResultCode.PARAM_ERROR;
  69. msg = ex.Message;
  70. }
  71. else
  72. {
  73. msg = "服务器好像出了点问题,请联系系统管理员...";
  74. error = $"{ex.Message}";
  75. Function.WriteLog(DateTime.Now.ToString() + "\n" + ex.ToString(), "Global全局异常");
  76. logLevel = NLog.LogLevel.Error;
  77. context.Response.StatusCode = 500;
  78. }
  79. var options = new textJson.JsonSerializerOptions
  80. {
  81. Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
  82. PropertyNamingPolicy = textJson.JsonNamingPolicy.CamelCase,
  83. WriteIndented = true
  84. };
  85. ApiResult apiResult = new(code, msg);
  86. string responseResult = textJson.JsonSerializer.Serialize(apiResult, options);
  87. // string ip = HttpContextExtension.GetClientUserIp(context);
  88. // var ip_info = IpTool.Search(ip);
  89. // SysOperLog sysOperLog = new()
  90. // {
  91. // Status = 1,
  92. // // OperIp = ip,
  93. // OperUrl = HttpContextExtension.GetRequestUrl(context),
  94. // RequestMethod = context.Request.Method,
  95. // JsonResult = responseResult,
  96. // ErrorMsg = string.IsNullOrEmpty(error) ? msg : error,
  97. // OperName = HttpContextExtension.GetName(context),
  98. // // OperLocation = ip_info.Province + " " + ip_info.City,
  99. // OperTime = DateTime.Now,
  100. // OperParam = HttpContextExtension.GetRequestValue(context, context.Request.Method)
  101. // };
  102. var endpoint = GetEndpoint(context);
  103. if (endpoint != null)
  104. {
  105. var logAttribute = endpoint.Metadata.GetMetadata<LogAttribute>();
  106. if (logAttribute != null)
  107. {
  108. // sysOperLog.BusinessType = (int)logAttribute.BusinessType;
  109. // sysOperLog.Title = logAttribute?.Title;
  110. // sysOperLog.OperParam = logAttribute.IsSaveRequestData ? sysOperLog.OperParam : "";
  111. // sysOperLog.JsonResult = logAttribute.IsSaveResponseData ? sysOperLog.JsonResult : "";
  112. }
  113. }
  114. LogEventInfo ei = new(logLevel, "GlobalExceptionMiddleware", error)
  115. {
  116. Exception = ex,
  117. Message = error
  118. };
  119. ei.Properties["status"] = 1;//走正常返回都是通过走GlobalExceptionFilter不通过
  120. ei.Properties["jsonResult"] = responseResult;
  121. // ei.Properties["requestParam"] = sysOperLog.OperParam;
  122. // ei.Properties["user"] = sysOperLog.OperName;
  123. Logger.Log(ei);
  124. context.Response.ContentType = "text/json;charset=utf-8";
  125. await context.Response.WriteAsync(responseResult, System.Text.Encoding.UTF8);
  126. // string errorMsg = $"> 操作人:{sysOperLog.OperName}" +
  127. // $"\n> 操作地区:{sysOperLog.OperIp}({sysOperLog.OperLocation})" +
  128. // $"\n> 操作模块:{sysOperLog.Title}" +
  129. // $"\n> 操作地址:{sysOperLog.OperUrl}" +
  130. // $"\n> 错误信息:{msg}\n\n> {error}";
  131. // SysOperLogService.InsertOperlog(sysOperLog);
  132. if (!notice) return;
  133. }
  134. public static Endpoint GetEndpoint(HttpContext context)
  135. {
  136. if (context == null)
  137. {
  138. throw new ArgumentNullException(nameof(context));
  139. }
  140. return context.Features.Get<IEndpointFeature>()?.Endpoint;
  141. }
  142. }
  143. }