作者:小5聊基础
简介:一只喜欢全栈方向的程序员,欢迎咨询,尽绵薄之力答疑解惑
编程原则:Write Less Do More
- 流程图
【基本信息】
1)操作系统:windows11 <br/>
2)开发工具:VS 2017 <br/>
3)开发语言:C# <br/>
4)开发框架:.net core 2.1 <br/>
5)关键类:IAsyncExceptionFilter <br/>
【创建全局异常过滤类】
技术日新月异,同一个功能,版本肯定会在不停更新升级,除非已经弃用,因此,需要针对版本进行使用,否则可能会因为版本不用导致报错<br/>
1)继承接口类,IAsyncExceptionFilter <br/>
类来自的dll为,Microsoft.AspNetCore.Mvc.Abstractions.dll <br/>
版本:2.1.1 <br/>
2)实现接口方法,OnExceptionAsync <br/>
关键对象,ExceptionContext context,在实现方法类直接接收这个参数即可,这个参数会在目标方法发生异常后,赋值到这个参数里 <br/>
3)判断是否已经处理过异常 <br/>
如果有设置了多重嵌套过滤,那么可能会在第一层就已处理,或者根据业务需求进行灵活设定context.ExceptionHandled==false; //未处理
4)请求协议 <br/>
可以根据http和https进行请求协议判断,也许在项目上需要对这两个请求协议做一个区别判断context.HttpContext.Request.IsHttps
5)请求地址 <br/>string url = http + context.HttpContext.Request.Host + context.HttpContext.Request.Path;
6)通过设置一个小技巧来判断,当前请求时api还是页面 <br/> [Route("api/[controller]/[action]")]
<br/>bool isApi = url.IndexOf("/api/") > 0 ? true : false;
<br/>
页面api标识来判断 <br/>
7)api和页面的post请求,响应json数据,页面get请求则返回页面信息
- 类全部代码
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Newtonsoft.Json;
using System;
using System.Text;
using System.Threading.Tasks;
namespace myweb.Class
{
/// <summary>
/// 异常处理 - 发生异常
/// </summary>
public class ExceptionFilter : IAsyncExceptionFilter
{
/// <summary>
/// 重写OnExceptionAsync方法,定义自己的处理逻辑
/// 测试方法-api:localhost:44345/api/LoginRegister/Test
/// 测试方法-页面:localhost:44345/Home/Test
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public Task OnExceptionAsync(ExceptionContext context)
{
try
{
if (context.ExceptionHandled == false)
{
//写入日志
//请求地址
string http = (context.HttpContext.Request.IsHttps ? "https://" : "http://");
string url = http + context.HttpContext.Request.Host + context.HttpContext.Request.Path;
bool isApi = url.IndexOf("/api/") > 0 ? true : false;
if (isApi)
{
var result = new
{
message = context.Exception.Message.ToString(),
code = 198
};
context.Result = new ContentResult
{
StatusCode = StatusCodes.Status200OK,
ContentType = "application/json;charset=utf-8",
Content = JsonConvert.SerializeObject(result)
};
}
else
{
StringBuilder errorMessage = new StringBuilder();
//请求类型
var method = context.HttpContext.Request.Method;
int code = context.HttpContext.Response.StatusCode;
if (method.ToLower() == "Get".ToLower())
{
errorMessage.Clear();
errorMessage.Append($"<meta name=\"viewport\" content=\"width=device-width, height=device-height, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no\">");
errorMessage.Append($"<h1>请求页面发生异常</h1>");
errorMessage.Append($"<p>URL:{url}</p>");
errorMessage.Append($"<p>StatusCode:{code}</p>");
errorMessage.Append($"<p>GET</p>");
context.HttpContext.Response.ContentType = "text/html;charset=utf-8";
context.HttpContext.Response.StatusCode = 200;
using (var responseStream = context.HttpContext.Response.Body)
{
responseStream.Write(Encoding.Default.GetBytes(errorMessage.ToString()));
}
}
else
{
errorMessage.Clear();
errorMessage.Append($"请求页面发生异常,");
errorMessage.Append($"URL:{ url},");
errorMessage.Append($"StatusCode:{code},");
errorMessage.Append($"POST");
var result = new
{
message = errorMessage.ToString(),
code = 404
};
context.HttpContext.Response.ContentType = "application/json;charset=utf-8";
context.HttpContext.Response.StatusCode = 200;
using (var responseStream = context.HttpContext.Response.Body)
{
responseStream.Write(Encoding.Default.GetBytes(JsonConvert.SerializeObject(result)));
}
}
}
}
}
catch (Exception exception)
{
//写入到txt
}
context.ExceptionHandled = true; //设置为true,表示异常已经被处理了
return Task.CompletedTask;
}
}
}
【Startup启动类设置】
1)在ConfigureServices方法下设置 <br/>
因为是针对MVC方法进行异常过滤处理,所以需要在AddMvc方法进行设置
- 部分代码
public IServiceProvider ConfigureServices(IServiceCollection services)
//===添加MVC组件===
services.AddMvc(options=> {
options.Filters.Add(typeof(ExceptionFilter)); //全局异常过滤
});