前言

一天天不知道怎么过的,但确实挺忙,事赶事不带停那种,让我感觉跟在流水线干活一样,忙活的事差不多了就喘口气继续补充这一系列的内容,前面几篇基本上把一个常规的后端服务搭建差不多了,后面的会时不时根据自己需要或者常规的测试内容来一点点完善更新。

拦截器

这里先不提AOP的内容,其实在我个人之前的理解,AOP开发的思想就是,我们做的某些操作例如身份验证,日志记录,异常抓捕等等这些操作,可以单独拎出来放那,谁用了加个头部标识就可以了,剩余的交给代码来处理,这样我们开发就只需要关心业务功能,而其他的全都可以不用考虑,这就是框架的好处,别人封装集成好,就可以省去很大的开发工作量。

好,开始说拦截器,其实也是中间层,个人感觉跟AOP的概念类似,就放到这里写上了。

异常拦截器

在我们Api的工程目录下新建文件夹Filters用于存放拦截器,之后我们新建ExceptionFilter这个异常的拦截器,用于记录工程抛异常并做对应回调处理。

代码如下,具体不过多解释,因为实在觉得这个没啥说的,只是注意异步调用的问题即可。

    public class ExceptionFilter
{
private readonly RequestDelegate _next; /// <summary>
///
/// </summary>
/// <param name="next"></param>
public ExceptionFilter(RequestDelegate next)
{
_next = next;
} /// <summary>
///
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception ex) //发生异常
{
context.Response.StatusCode = 500;
LogUtil.Error($"response exception:{ex.Message}");// {ex.StackTrace}
await ResponseUtil.HandleExceptionAsync(500, "服务器错误");
}
}
}

这个地方的ResponseUtil是单独在Util层创建的(公共类尽量扔到同一个工程类库下,以后一键打包,各种复用)。

    public class ResponseUtil
{
/// <summary>
/// 回调
/// </summary>
/// <param name="statusCode">html状态码</param>
/// <param name="msg">消息</param>
/// <returns></returns>
public static Task HandleExceptionAsync(int statusCode, string msg)
{
var data = new { code = statusCode, msg = msg };
string text = JsonConvert.SerializeObject(data);
var response = AprilConfig.HttpCurrent.Response;
if (string.IsNullOrEmpty(response.ContentType))
{
//跨域的时候注意,不带header没法接收回调
response.Headers.Add("Access-Control-Allow-Origin", "*");
response.Headers.Add("Access-Control-Allow-Credentials", "true");
//因为这个是json
response.ContentType = "application/json;charset=utf-8";
response.StatusCode = 200;
response.ContentLength = text.Length;
return response.WriteAsync(text);
}
else
{
return response.WriteAsync(text);
}
}
}

之后我们依然要在Startup中注册我们这个中间层。

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseMiddleware<ExceptionFilter>();
…
}

这样我们在全局如果出现异常的时候,可以统一捕获到问题,然后做记录,当然在测试环境下注意,如果这个错误帮助页打开的时候,那上面的拦截器将毫无乱用。

测试结果



这样如果真是哪个地方没有做异常捕获,全局最终都会一个不漏的抓住然后告诉你,好处是如果懒那就所有地方都不写了,问题是有些异常即使捕获但是不需要告知用户也不需要做记录(比如文件上传下载的线程中断异常之类的),所以这个只是为了保险起见而不是为了省事。

身份验证拦截器

接下来我们继续创建一个AuthFilter,目的是做身份验证的判断,如果没通过就没必要再进入具体的控制器了。

    public class AuthFilter
{
private readonly RequestDelegate _next; public AuthFilter(RequestDelegate next)
{
_next = next;
} public Task Invoke(HttpContext context)
{
if (context.Request.Method == "OPTIONS")
{
return _next(context);
}
var headers = context.Request.Headers;
//检查头文件是否有jwt token
if (!headers.ContainsKey("Authorization"))
{
string path = context.Request.Path.Value;
if (!AprilConfig.AllowUrl.Contains(path) && path.IndexOf("swagger") < 0)
{
//这里做下相关的身份校验
return ResponseUtil.HandleExceptionAsync(401, "请登录"); //判断是否有权限查看(在身份验证后判断对应的权限,这个方法后续再写)
return ResponseUtil.HandleExceptionAsync(-2, "无权访问"); }
}
return _next(context);
}
}

同样我们需要在Startup注册使用中间层。

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseMiddleware<ExceptionFilter>();
app.UseMiddleware<AuthFilter>();
…
}

测试



然后访问我们的Swagger,效果就很明显了。

小结

这一篇主要就是引入中间层的使用,个人认为什么AOP开发OOP开发完全因人而异,没必要为了追求新技术而去整体大功能改造,新技术确实使用起来方便,也有很好的前景,但是对于企业来讲,稳定是最重要的,不会为了1%的性能速度而去冒30%甚至更高的风险,但是我还是要说一句,net core到目前为止已经历过一个大版本的更新,虽然3.0没有正式发布,但是一个个版本的更新之后,稳定性已经很ok了,所以该吃螃蟹都可以动手了。

下一篇,继续引入AOP的开发,主要用的第三方的组件AspectCore,将针对接口调用的时候做一些常规操作。


补充 2019-07-31

今天在做调试的时候发现一个问题,现状如下



发现这个问题我的第一反应是,字符编码,但是看到我回调的时候明显已经设置了ContentType,所以这个应该不是错误的原因,但是多次刷新的测试结果是偶尔正常,怪异的情况总是伴随着bug,于是比对了正确的回调信息和错误的回调信息(这里是通过chrome浏览器调试然后获取的回调信息,具体调试方法后续前端介绍,当然基本上都知道)。



这样一看发现了问题所在,所以这个地方决定不再自主去设置Length了。

net core Webapi基础工程搭建(七)——小试AOP及常规测试_Part 1的更多相关文章

  1. net core Webapi基础工程搭建(六)——数据库操作_Part 2

    目录 前言 开始 使用 小结 前言 昨天是写着写着发现,时间不早了,已经养成了晚上下班抽时间看看能写点儿啥的习惯(貌似),今天实在是不想让昨天没做完的事情影响,所以又坐下,沉下心(周末了),开始把数据 ...

  2. net core Webapi基础工程搭建(六)——数据库操作_Part 1

    目录 前言 SqlSugar Service层 BaseService(基类) 小结 前言 后端开发最常打交道的就是数据库了(静态网站靠边),上一篇net core Webapi基础工程搭建(五)-- ...

  3. net core Webapi基础工程搭建(七)——小试AOP及常规测试_Part 2

    目录 前言 引入 自定义属性 测试 小结 前言 前一篇讲到了中间层的使用,可能不是那么AOP,今天主要来说下一个轻量级的AOP第三方类库AspectoCore. 简单介绍下这个类库,AspectCor ...

  4. net core Webapi基础工程搭建(五)——缓存机制

    目录 前言 Cache Session Cookie 小结 补充 前言 作为WebApi接口工程,性能效率是必不可少的,每次的访问请求,数据库读取,业务逻辑处理都或多或少耗费时间,偶尔再来个各种花式f ...

  5. net core Webapi基础工程搭建(二)——创建工程

    目录 前言 创建工程 工程文件概述(个人理解) 运行 小结 前言 前面介绍了开发工具及net core版本,后端工程的框架结构开发工具及环境,因为是基础工程,所以没考虑太复杂的框架,如果有架构师请勿喷 ...

  6. net core Webapi基础工程搭建(一)——开发工具及环境

    目录 开发工具 版本 后端框架 开发工具 Visual Studio 2019,既然要折腾那就体验最新版的开发工具有什么特殊的地方,之前个人开发使用的是2017. 下载地址:https://visua ...

  7. net core Webapi基础工程搭建(四)——日志功能log4net

    目录 前言 log4net 依然是,NuGet引用第三方类库 整合LogUtil 小结 前言 一个完整的项目工程离不开日志文件的记录,而记录文件的方法也有很多,可以自己通过Stream去实现文件的读写 ...

  8. net core Webapi基础工程搭建(三)——在线接口文档Swagger

    目录 前言 Swagger NuGet引用第三方类库 别急,还有 没错,注释 小结 前言 前后分离的好处,就是后端埋头做业务逻辑功能,不需要过多考虑用户体验,只专注于数据.性能开发,对于前端需要的数据 ...

  9. 第十九节:Asp.Net Core WebApi基础总结和请求方式

    一. 基础总结 1.Restful服务改造 Core下的WebApi默认也是Restful格式服务,即通过请求方式(Get,post,put,delete)来区分请求哪个方法,请求的URL中不需要写方 ...

随机推荐

  1. I/O:ByteBuffer

    ByteBuffer: static ByteBuffer allocate(int capacity) :分配一个新的字节缓冲区. static ByteBuffer allocateDirect( ...

  2. 【素数的判定-从暴力到高效】-C++

    今天我们来谈一谈素数的判定. 对于每一个OIer来说,在漫长的练习过程中,素数不可能不在我们的眼中出现,那么判定素数也是每一个OIer应该掌握的操作,那么我们今天来分享几种从暴力到高效的判定方法. 1 ...

  3. 动态规划(1)——最长子序列(LCS)问题

    最长子序列问题:从中找出最长的字符序列,比如: cnblogs和belong.这两个字符串的最长子序列就是blog. 动态规划:通过分解大问题,不断的将大问题变成小问题,最终整合所有解,得出最优解(和 ...

  4. NOIP2018普及T2暨洛谷P5016 龙虎斗

    题目链接:https://www.luogu.org/problemnew/show/P5016 分析: 这是一道模拟题.看到题目,我们首先要把它细致的读明白,模拟题特别考察细节,往往会有想不到的坑点 ...

  5. [leetcode] 238. Product of Array Except Self (medium)

    原题 思路: 注意时间复杂度,分别乘积左右两边,可达到O(n) class Solution { public: vector<int> productExceptSelf(vector& ...

  6. Windows 设置自启动计划任务(非登录启动)

    原因:服务器会不定期重启,且重启后无人看管,不会有人去登录系统.导致我们做的一些开机启动程序失效,进而系统瘫痪. 解决方法: 自己理解,想要达到目的有两种方式:系统服务 & 计划任务配置. 计 ...

  7. K2 smarforms 控件整理

    K2 Community – Market – Smatform Controls l   K2 blackpearl 1.    Drag and Drop Upload Control http: ...

  8. Linux更换默认Security源

    很多时候 修改了软件源,但是发现更新还是很慢,查看一下,如下图,有一个security ,显然主源还是在ubuntu,ubuntu本身在国外,所以很慢,因此考虑替换为国内镜像. 图1 1.备份数据源列 ...

  9. thinkphp项目阿里云ECS服务器部署

    [日记]thinkphp项目阿里云ECS服务器部署   项目本地开发告一段落.准备上传到服务器上测试 技术组成 thinkphp+mysql+阿里ECS  代码管理方式git 一.阿里ECS服务器配置 ...

  10. 说说Java线程间通信

    序言 正文 [一] Java线程间如何通信? 线程间通信的目标是使线程间能够互相发送信号,包括如下几种方式: 1.通过共享对象通信 线程间发送信号的一个简单方式是在共享对象的变量里设置信号值:线程A在 ...