asp.net core webapi 返回结果通用化+异常处理和日志记录
1. 返回结果通用化
在common文件中新建ApiResult.cs文件用于实现返回结果通用化
在common文件中新建ApiResult.cs文件用于实现返回结果通用化
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace xxxxx { /// <summary> /// 统一返回接口格式 /// </summary> public class ApiResult { /// <summary> /// 是否正常返回状态 /// </summary> public bool Success { get; set; } /// <summary> /// 处理消息 /// </summary> public string? Message { get; set; } } public class ApiDataResult<T> : ApiResult { /// <summary> /// 结果集 /// </summary> public T? Data { get; set; } /// <summary> /// 沉余结果 /// </summary> public object? OValue { get; set; } } }
2. 实现全局异常处理
新建Utility文件夹,里面新建Filters文件夹,在里面新建CustomAsyncExceptionFilterAttribute.cs用于处理全局异常
因为 CustomAsyncExceptionFilterAttribute 类中使用了log4net,所以需要nuget安装如下几个包
log4net
log4net.Ext.Json.Net
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Zhaoxi.Manage.Common; namespace xxxxxxxxxx { /// <summary> /// 异常处理 /// </summary> public class CustomAsyncExceptionFilterAttribute : Attribute, IAsyncExceptionFilter { private ILogger<CustomAsyncExceptionFilterAttribute> _logger; /// <summary> /// 构造函数 /// </summary> public CustomAsyncExceptionFilterAttribute(ILogger<CustomAsyncExceptionFilterAttribute> logger) { _logger = logger; } /// <summary> /// 用作处理异常的 /// </summary> /// <param name="context"></param> /// <returns></returns> public async Task OnExceptionAsync(ExceptionContext context) { if(context.ExceptionHandled == false) { _logger.LogError($"发生了错误: {context.Exception.Message}"); context.Result = new JsonResult(new ApiResult() { Success = false, Message = context.Exception.Message }) ; } context.ExceptionHandled = true; await Task.CompletedTask; } } }
然后再启动文件中配置
builder.Services.AddControllers(option => { //表示支持全局的异常处理 option.Filters.Add<CustomAsyncExceptionFilterAttribute>(); });
3. 日志记录-----新建文件夹CfgFile, 并在里面新建 log4net.Config文件
需要安装两个nuget包:
System.Data.SqlClient
Microsoft.Extensions.Logging.Log4Net.AspNetCore
注: 需要将log4net.Config设置为始终复制
<?xml version="1.0" encoding="utf-8"?> <log4net> <!-- Define some output appenders --> <appender name="rollingAppender" type="log4net.Appender.RollingFileAppender"> <file value="log4\log.txt" /> <!--追加日志内容--> <appendToFile value="true" /> <!--防止多线程时不能写Log,官方说线程非安全--> <lockingModel type="log4net.Appender.FileAppender+MinimalLock" /> <!--可以为:Once|Size|Date|Composite--> <!--Composite为Size和Date的组合--> <rollingStyle value="Composite" /> <!--当备份文件时,为文件名加的后缀--> <datePattern value="yyyyMMdd.TXT" /> <!--日志最大个数,都是最新的--> <!--rollingStyle节点为Size时,只能有value个日志--> <!--rollingStyle节点为Composite时,每天有value个日志--> <maxSizeRollBackups value="20" /> <!--可用的单位:KB|MB|GB--> <maximumFileSize value="3MB" /> <!--置为true,当前最新日志文件名永远为file节中的名字--> <staticLogFileName value="true" /> <!--输出级别在INFO和ERROR之间的日志--> <filter type="log4net.Filter.LevelRangeFilter"> <param name="LevelMin" value="ALL" /> <param name="LevelMax" value="FATAL" /> </filter> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/> </layout> <!--<layout type="Zhaoxi.Manage.ApiServer.Utility.Log4netExt.CustomLogLayout"> <conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/> </layout>--> </appender> <!--SqlServer形式--> <!--log4net日志配置:http://logging.apache.org/log4net/release/config-examples.html --> <appender name="AdoNetAppender_SqlServer" type="log4net.Appender.AdoNetAppender"> <!--日志缓存写入条数 设置为0时只要有一条就立刻写到数据库--> <bufferSize value="0" /> <connectionType value="System.Data.SqlClient.SqlConnection,System.Data.SqlClient, Version=4.6.1.3, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> <connectionString value="你的连接数据库字符串" /> <commandText value="INSERT INTO Log4Net ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" /> <parameter> <parameterName value="@log_date" /> <dbType value="DateTime" /> <layout type="log4net.Layout.RawTimeStampLayout" /> </parameter> <parameter> <parameterName value="@thread" /> <dbType value="String" /> <size value="255" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%thread" /> </layout> </parameter> <parameter> <parameterName value="@log_level" /> <dbType value="String" /> <size value="50" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%level" /> </layout> </parameter> <parameter> <parameterName value="@logger" /> <dbType value="String" /> <size value="255" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%logger" /> </layout> </parameter> <parameter> <parameterName value="@message" /> <dbType value="String" /> <size value="4000" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%message" /> </layout> </parameter> <parameter> <parameterName value="@exception" /> <dbType value="String" /> <size value="2000" /> <layout type="log4net.Layout.ExceptionLayout" /> </parameter> </appender> <root> <!--控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF--> <!--OFF:0--> <!--FATAL:FATAL--> <!--ERROR: ERROR,FATAL--> <!--WARN: WARN,ERROR,FATAL--> <!--INFO: INFO,WARN,ERROR,FATAL--> <!--DEBUG: INFO,WARN,ERROR,FATAL--> <!--ALL: DEBUG,INFO,WARN,ERROR,FATAL--> <priority value="ALL"/> <level value="INFO"/> <appender-ref ref="rollingAppender" /> <appender-ref ref="AdoNetAppender_SqlServer" /> </root> </log4net>
然后再启动文件中配置如下
//需要安装nuget包: Microsoft.Extensions.Logging.Log4Net.AspNetCore builder.Logging.AddLog4Net("CfgFile/log4net.Config");