1、使用中间件或者全局异常过滤器可以很大程度上减少你的冗余代码,提升代码的美观以及可维护性。
2、这种做法在行内,也称之为 微服务。
废话不多说,直接上代码
// 异常处理过滤器
using log4net;
using log4net.Config;
using log4net.Repository;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Filters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace AspDotNetGo.Common
{
public class ExceptionFilter : IExceptionFilter, IAsyncExceptionFilter
{
private readonly ILog log;
public ExceptionFilter(ILog _log)
{
log = _log;
}
public void OnException(ExceptionContext context)
{
//捕获到程序未处理的异常,通常是用文档记录下来
#region 此代码块中代码可以修改为自己的代码
if (context.HttpContext.Request.IsHttps)
{
//ILoggerRepository repository = LogManager.CreateRepository("NETCoreRepository");
// 默认简单配置,输出至控制台
//BasicConfigurator.Configure(repository);
//ILog log = LogManager.GetLogger(repository.Name, "NETCorelog4net");
log.Info(typeof(ExceptionHandle).ToString() + $"捕获全局异常:{context.Exception.Message},{context.Exception.StackTrace},【错误】{context.Exception.ToString()}");
Console.ReadKey();
context.ExceptionHandled = true;
}
else
{
context.ExceptionHandled = true;
}
#endregion
}
public Task OnExceptionAsync(ExceptionContext context)
{
OnException(context);
return Task.CompletedTask;
}
}
}
// 异常处理中间件
using log4net;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace AspDotNetGo.Common
{
public class ExceptionHandle
{
private readonly ILog log;
private readonly RequestDelegate next;
///
///
///
///
public ExceptionHandle(RequestDelegate next, ILog _log)
{
log = _log;
this.next = next;
}
public async Task Invoke(HttpContext context)
{
try
{
await next(context);
}
catch (Exception e)
{
await HandleExceptionAsync(context, e).ConfigureAwait(false);
}
}
public async Task HandleExceptionAsync(HttpContext context, Exception exception)
{
if (exception == null)
{
return;
}
await WriteExceptionAsync(context, exception).ConfigureAwait(false);
}
private async Task WriteExceptionAsync(HttpContext context, Exception exception)
{
try
{
var baseException = exception.GetBaseException();
if (baseException == null)
{
baseException = exception;
}
Console.WriteLine(typeof(ExceptionHandle).ToString()+ $"捕获全局异常:{baseException.Message},{baseException.StackTrace},【错误】{baseException.ToString()}");
log.Info(typeof(ExceptionHandle).ToString() + $"捕获全局异常:{baseException.Message},{baseException.StackTrace},【错误】{baseException.ToString()}");
var response = context.Response;
response.ContentType = "application/json;charset=utf-8";
string message = "调用API失败";
object data = null;
//#if DEBUG
message = baseException.Message;
data = baseException.StackTrace;
//#endif
//var result = ExcutedResult.FailedResult(message);
await response.WriteAsync(message).ConfigureAwait(false);
}
catch (Exception ex)
{
Console.WriteLine(typeof(ExceptionHandle).ToString()+ "处理全局异常时引发额外的异常:" + ex.Message);
}
}
}
}
// 注入相关组件 我这里有EF以及Freesql的一些东西,不需要的可以自己注释掉
using AspDotNetGo.Common;
using AspDotNetGo.Models;
using log4net;
using log4net.Config;
using log4net.Repository;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using MyLogin.WebApi.Utility.AutoMapper;
using System.IO;
namespace AspDotNetGo
{
public class Startup
{
public IConfiguration Configuration { get; }
public static ILoggerRepository repository { get; set; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext();
services.AddMvc(options =>
{
// 注入全局处理异常过滤器(选其一)
options.Filters.Add();
});
repository = LogManager.CreateRepository("NETCoreRepository");
XmlConfigurator.Configure(repository, new FileInfo("log4net.config"));
var log = LogManager.GetLogger(repository.Name, typeof(Startup));
services.AddSingleton(log);
IFreeSql fsql = new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.MySql, Configuration["ConnectionStrings:MySQL"]) //可以写入json文件
.UseAutoSyncStructure(true) //自动同步实体结构到数据库,FreeSql不会扫描程序集,只有CRUD时才会生成表。
.Build(); //请务必定义成 Singleton 单例模式
services.AddSingleton(fsql);
services.AddControllers();
services.AddSwaggerGen();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// 注入全局处理异常中间件
//app.UseMiddleware();
app.UseRouting();
app.UseSwagger();
app.UseSwaggerUI();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
// 添加log4net.config配置文件
运行结果:
异常截获成功,并记入日志。
如果你觉得本文对你有帮助,请点击“推荐”,谢谢。



