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

前言

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

拦截器

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

好,开始说拦截器,其实也是中间层,我的感受跟AOP的概念相似,就放到这里写上了。json

异常拦截器

在咱们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>();
            …
        }

这样咱们在全局若是出现异常的时候,能够统一捕获到问题,而后作记录,固然在测试环境下注意,若是这个错误帮助页打开的时候,那上面的拦截器将毫无乱用。app

Startup

测试结果

测试

日志记录
这样若是真是哪一个地方没有作异常捕获,全局最终都会一个不漏的抓住而后告诉你,好处是若是懒那就全部地方都不写了,问题是有些异常即便捕获可是不须要告知用户也不须要作记录(好比文件上传下载的线程中断异常之类的),因此这个只是为了保险起见而不是为了省事。框架

身份验证拦截器

接下来咱们继续建立一个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,效果就很明显了。

Swagger

小结

这一篇主要就是引入中间层的使用,我的认为何AOP开发OOP开发彻底因人而异,不必为了追求新技术而去总体大功能改造,新技术确实使用起来方便,也有很好的前景,可是对于企业来说,稳定是最重要的,不会为了1%的性能速度而去冒30%甚至更高的风险,可是我仍是要说一句,net core到目前为止已经历过一个大版本的更新,虽然3.0没有正式发布,可是一个个版本的更新以后,稳定性已经很ok了,因此该吃螃蟹均可以动手了
下一篇,继续引入AOP的开发,主要用的第三方的组件AspectCore,将针对接口调用的时候作一些常规操做。


补充 2019-07-31

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

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

比对结果
这样一看发现了问题所在,因此这个地方决定再也不自主去设置Length了。

解决

相关文章
相关标签/搜索