前言

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

拦截器

这里先不提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. thread学习笔记--BackgroundWorker 类

    背景: 在 WinForms 中,有时要执行耗时的操作,比如统计某个磁盘分区的文件夹或者文件数目,如果分区很大或者文件过多的话,处理不好就会造成“假死”的情况,或者报“线程间操作无效”的异常,或者在该 ...

  2. 洛谷P1129 [ZJOI2007]矩阵游戏 题解

    题目链接:https://www.luogu.org/problemnew/show/P1129 分析: 这道题不是很好想,但只要想的出来,代码不成问题. 思路1 举几个例子,我们发现, 对于任何数来 ...

  3. CentOS 7.3 配置静态ip

    镜像:CentOS-7-x86_64-DVD-1511.iso 1.修改.查看虚拟机的网段 1.1.查看虚拟机网段 编辑-> 虚拟机网络编辑器,修改的需要管理员权限 选择NAT模式 点击 NAT ...

  4. JS实现当前页弹出窗口,且页面变灰不可操作

    使用JS在当前页面在div中加载弹出窗口,并让当前页面变灰不可操作. 加载弹出窗口的div需将宽高设置成整个页面的大小,以覆盖当前页面的内容. opacity:0.6: 页面可见度设置为0.6(1为完 ...

  5. Hadoop值Partition分区

    分区操作 为什么要分区? 要求将统计结果按照条件输出到不同文件中(分区).比如:将统计结果按 照手机归属地不同省份输出到不同文件中(分区) 默认 partition 分区 /** 源码中:numRed ...

  6. 6.2.初识Flutter应用之路由管理

    路由管理 路由(Route)在移动开发中通常指页面(Page),这跟web开发中单页应用的Route概念意义是相同的,Route在Android中通常指一个Activity,在iOS中指一个ViewC ...

  7. 如何挑选node docker镜像

    如何挑选node docker镜像 在使用Jenkins构建前端项目的时候遇到一点问题: node的版本问题. 由于可能编译的项目历史不同,所依赖的node版本也各有千秋,直接把所有项目都升级到最新的 ...

  8. wp伪静态网页打开慢之提速方案1s内打开 wp的静态化插件测试

    自上篇文章,我做了伪静态话.可是伪静态访问还是php动态页面,还需要服务端分析如何处理,访问页面时会发现有一个漫长的等待响应的时间.这是打开速度在4s左右.而静态页面则是直接打开,不需要服务器操作,不 ...

  9. 用margin还是padding ?

    margin是用来隔开元素与元素的间距:padding是用来隔开元素与内容的间隔. margin用于布局分开元素使元素与元素互不相干:padding用于元素与内容之间的间隔,让内容(文字)与(包裹)元 ...

  10. shiro创建配置对象

    在执行 Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory(&quo ...