1、自定义中间件处理异常(推荐) 参考:https://www.csframework.com/archive/1/arc-1-20211230-4180.htm
注入中间件
方式1:app.UseMiddleware<ExceptionHandlingMiddleware>();然后在Action或者Service中直接抛异常,就会走异常处理。
方式2:使用扩展方法
using System.Net;
using System.Text.Json;
using ExceptionHandling.Models.Responses;
namespace ExceptionHandling.Middlewares;
public class ExceptionHandlingMiddleware
{
private readonly RequestDelegate _next; // 用来处理上下文请求
private readonly ILogger<ExceptionHandlingMiddleware> _logger;
public ExceptionHandlingMiddleware(RequestDelegate next,ILogger<ExceptionHandlingMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext httpContext)
{
try
{
await _next(httpContext); //要么在中间件中处理,要么被传递到下一个中间件中去
}
catch (Exception ex)
{
//_logger.LogError(ex, "##异常来源:{0}", httpContext.Request.Path);//直接记录ex
await HandleExceptionAsync(httpContext, ex); // 捕获异常了在HandleExceptionAsync中处理
}
}
private async Task HandleExceptionAsync(HttpContext context, Exception exception)
{
context.Response.ContentType = "application/json"; // 返回json 类型
var response = context.Response;
var errorResponse = new ErrorResponse
{
Success = false
}; // 自定义的异常错误信息类型
switch (exception)
{
case ApplicationException ex:
if (ex.Message.Contains("Invalid token"))
{
response.StatusCode = (int) HttpStatusCode.Forbidden;
errorResponse.Message = ex.Message;
break;
}
response.StatusCode = (int) HttpStatusCode.BadRequest;
errorResponse.Message = ex.Message;
break;
case KeyNotFoundException ex:
response.StatusCode = (int) HttpStatusCode.NotFound;
errorResponse.Message = ex.Message;
break;
default:
response.StatusCode = (int) HttpStatusCode.InternalServerError;
errorResponse.Message = "Internal Server errors. Check Logs!";
break;
}
_logger.LogError(exception.Message);
var result = JsonSerializer.Serialize(errorResponse);
await context.Response.WriteAsync(result);
}
}
public class ErrorResponse
{
public int StatusCode { get; set; }
public string Message { get; set; } = string.Empty;
public bool Success { get; set; }
}
方式1:app.UseMiddleware<ExceptionHandlingMiddleware>();然后在Action或者Service中直接抛异常,就会走异常处理。
方式2:使用扩展方法
// Extension method used to add the middleware to the HTTP request pipeline. public static class ExceptionHandlingMiddlewareExtensions { public static IApplicationBuilder UseExceptionHandlingMiddleware(this IApplicationBuilder builder) { return builder.UseMiddleware<ExceptionHandlingMiddleware>(); } }
2、使用过滤器 参考:https://blog.csdn.net/Daniel_yka/article/details/121062319
public class CustomExceptionFilterAttribute: ExceptionFilterAttribute
{
private readonly ILogger<WeatherForecastController> _logger;
public CustomExceptionFilterAttribute(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
public override void OnException(ExceptionContext context)
{
//判断该异常有没有处理
if (!context.ExceptionHandled)
{
_logger.LogError($"Path:{context.HttpContext.Request.Path}Message:{context.Exception.Message}");
context.Result = new JsonResult(new {Reslut = false,Msg = "发生异常,请联系管理员"});
context.ExceptionHandled = true;
}
}
}
然后再在Startup下面的ConfigureServices注册这个类:services.AddControllers(o=>o.Filters.Add(typeof(CustomExceptionFilterAttribute)));
此时当程序中有异常,便会进入该方法,我们就能在这里统一管理异常。
log4net使用:
引入包:Microsoft.Extensions.Logging
Microsoft.Extensions.Logging.Log4Net.AspNetCore
配置日志
builder.Host.ConfigureDefaults(args).ConfigureLogging(p => { p.AddFilter("System", LogLevel.Warning); //过滤掉系统默认的一些日志 p.AddFilter("Microsoft", LogLevel.Warning);//过滤掉系统默认的一些日志 var path = Directory.GetCurrentDirectory() + "\\log4net.config"; //不带参数:表示log4net.config的配置文件就在应用程序根目录下,也可以指定配置文件的路径 p.AddLog4Net(path); });
根目录log4net.config
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout" value="%date [%thread] %-5level %logger - %message%newline" />
</appender>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file value="log-file.log" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="logfile/" />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<staticLogFileName value="false" />
<datePattern value="yyyyMMdd'.log'" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="1MB" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<!-- Setup the root category, add the appenders and set the default level -->
<root>
<level value="ALL" />
<appender-ref ref="ConsoleAppender" />
<appender-ref ref="FileAppender" />
<appender-ref ref="RollingLogFileAppender" />
</root>
</log4net>
构造函数注入:private readonly ILogger<HomeController> _logger;
_logger.LogInformation("test log info");
浙公网安备 33010602011771号