Mbp应用服务层的AOP实现

实现方法:asp.net core mvc 筛选器 + 中间件

日志,事务,和接口返回结果统一格式化采用操作筛选器,而异常处理采用中间件来处理.

最开始,我是打算用autofac的高级特性的拦截器来做AOP的,但是遇到一个问题,poco controller没办法注入到autofac的容器里面.导致拦截器不能正常工作,所以就采用了筛选器来做.这里的场景有以下几个:

  • AOP是在应用层,而应用层是用poco controller做的,而在asp.net core web api的基架中,controller处在管线的末端.所以可以在这层进行全局拦截.
  • 中间件处理异常更加灵活,可以有更多的定制化需求,而异常筛选器是响应抓捕的异常来处理,它相当于是异常发生后的一个处理程序,而中间件可以来实现类似异常筛选器.
  • 中间件不短路,只是在程序运行的管线上添加了try catch,同时也解决了异步方法出现的异常无法被捕获的问题.

实现代码

  • Mbp.AspNetCore.Filter 添加MbpLogFilter,MbpTransActionFilter,ResponseMiddleware三个操作筛选器
  • Mbp.AspNetCore.Middleware 添加MbpGlobaExceptionMiddleware中间件
  • 在模块MbpAspNetCoreModule中注册筛选器和中间件
public override IServiceCollection AddServices(IServiceCollection services)
{
services.AddMvc().AddNewtonsoftJson(options =>
{
// 忽略循环引用
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
// 不使用驼峰
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
// 设置时间格式
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
}).AddMvcOptions(options =>
{
// 禁用Version的绑定
options.ModelMetadataDetailsProviders.Add(new ExcludeBindingMetadataProvider(typeof(System.Version))); // 统一事务处理中间件
options.Filters.Add(typeof(MbpTransActionFilter)); // 统一日志处理中间件
options.Filters.Add(typeof(MbpLogFilter)); // 请求响应统一格式处理中间件
options.Filters.Add(typeof(ResponseMiddleware)); }); ; AddAutoWebApi(services, new AutoWebApiOptions()); // 创建Cors策略
services.AddCors(options =>
{
options.AddPolicy("MbpCors",
builder =>
{
builder.WithOrigins(services.BuildServiceProvider().GetService<IConfiguration>().GetSection("AllowedHosts").Value)
.AllowAnyMethod()
.AllowAnyHeader(); ;
});
}); return base.AddServices(services);
} public override void UseModule(IApplicationBuilder app)
{
// 启用跨域请求中间件
app.UseCors("MbpCors"); // 启用应用服务层全局错误处理中间件
app.UseMiddleware(typeof(MbpGlobaExceptionMiddleware)); base.UseModule(app);
}

异常中间件对并发冲突进行单独处理

 public async Task InvokeAsync(HttpContext context, ILogger<MbpGlobaExceptionMiddleware> logger)
{
try
{
// Call the next delegate/middleware in the pipeline
await _next(context);
}
catch (DbUpdateConcurrencyException ex)
{
// 发生冲突时候,牺牲后者.不做具体数据合并操作.提示当前用户数据已经发生修改,需要重试.
logger.LogError("并发冲突:" + ex.Message); context.Response.ContentType = "application/json"; await context.Response.WriteAsync(JsonConvert.SerializeObject(new { Code = 500, Message = "提交并发冲突", Version = "1", Data = new List<object>() }));
}
catch (Exception ex)
{
// 其他异常
logger.LogError($"请求[{context.Request.Path}]发生异常:" + ex.Message); context.Response.ContentType = "application/json"; await context.Response.WriteAsync(JsonConvert.SerializeObject(new { Code = 500, Message = "服务器异常", Version = "1", Data = new List<object>() }));
}
}

代码详细地址:https://github.com/mbpframework/Mbp

Mbp通过筛选器和中间件实现异常,日志,事务及接口返回数据格式化aop处理.的更多相关文章

  1. WebApi自定义全局异常过滤器及返回数据格式化

    WebApi在这里就不多说了,一种轻量级的服务,应用非常广泛.我这这里主要记录下有关 WebApi的相关知识,以便日后使用. 当WebApi应用程序出现异常时,我们都会使用到异常过滤器进行日志记录,并 ...

  2. springboot 接口返回数据时 net.sf.json.JSONNull["empty"]) 异常

    @ResetController返回数据时出现异常 Could not write JSON: Object is null; nested exception is com.fasterxml.ja ...

  3. MVC四大筛选器—ActionFilter&ResultedFilter

    AuthorizeFilter筛选器 在Action的执行中包括两个重要的部分,一个是Action方法本身逻辑代码的执行,第二个就是Action方法的筛选器的执行. MVC4中筛选器都是以AOP(面向 ...

  4. ISAPI筛选器及对ASP源文件的保护

    ISAPI筛选器及对ASP源文件的保护 2009-04-21 01:45:57 标签:ISAPI 筛选器 ASP 源文件 保护 摘要:本文介绍了利用ISAPI筛选器保护ASP源文件的方法,并给出一个实 ...

  5. MVC四大筛选器—AuthorizeFilter

    在Action的执行中包括两个重要的部分,一个是Action方法本身逻辑代码的执行,第二个就是Action方法的筛选器的执行. MVC4中筛选器都是以AOP(面向方面编程)的方式来设计的,通过对Act ...

  6. 如何添加筛选器 (Reporting Services)

    如果您希望在计算或显示时包含或排除特定值,可向数据集.数据区域或组添加筛选器.在运行时应用筛选器的顺序为:先对数据集,再对数据区域,最后对组,并按照组层次结构自上而下的顺序.在表.矩阵或列表中,对行组 ...

  7. Magicodes.IE之导入导出筛选器

    总体设计   Magicodes.IE是一个导入导出通用库,支持Dto导入导出以及动态导出,支持Excel.Word.Pdf.Csv和Html.在本篇教程,笔者将讲述如何使用Magicodes.IE的 ...

  8. Asp.net Core 异常日志与API返回值处理

    需求: 1.对异常进行捕获记录日志 并且修改返回值给前端 解释: ILogger4是自定义的一个日志,更改它就好 解决方案1: 使用中间件进行异常捕获并且修改其返回值 public class Err ...

  9. C# 之 读取Word时发生 “拒绝访问” 及 “消息筛选器显示应用程序正在使用中” 异常的处理

    1.Asp.net中建立Microsoft.Office.Interop.Word.Application时出现 “ 拒绝访问 ” 错误 项目中要实现在服务器端打开一个Word模版文件,修改其内容后再 ...

随机推荐

  1. Cocos Creator | 飞刀大乱斗开发教程系列(二)

    预览效果 具体内容 ■ 这一期,主要讲解主页中间人物效果的实现.也就是,在下方列表选择不同人物,上方显示不同的人物,播放不同的效果,即下图的效果实现,此部分也是采用预制 Prefab 进行实现. 英雄 ...

  2. redis集群数据迁移txt版

    ./redis-trib.rb create --replicas 1 192.168.112.33:8001 192.168.112.33:8002 192.168.112.33:8003 192. ...

  3. 【题解】BZOJ4883: [Lydsy1705月赛]棋盘上的守卫(最小生成基环森林)

    [题解]BZOJ4883: [Lydsy1705月赛]棋盘上的守卫(最小生成基环森林) 神题 我的想法是,每行每列都要有匹配且一个点只能匹配一个,于是就把格点和每行每列建点出来做一个最小生成树,但是不 ...

  4. Elasticsearch调优篇-慢查询分析笔记

    前言 elasticsearch提供了非常灵活的搜索条件给我们使用,在使用复杂表达式的同时,如果使用不当,可能也会为我们带来了潜在的风险,因为影响查询性能的因素很多很多,这篇笔记主要记录一下慢查询可能 ...

  5. Kubernetes资源与对象简述

    资料 k8s基本对象概念 背景 资源和对象   Kubernetes 中的所有内容都被抽象为"资源",如 Pod.Service.Node 等都是资源."对象" ...

  6. FIND_IN_SET 精确查找

    FIND_IN_SET(str,strlist) mysql专为精确匹配字符串而设置的函数 一个字符串列表就是一个由一些被‘,’符号分开的自链组成的字符串 1,2,3,4,5,6,7,8,9: 此函数 ...

  7. 11.在Chrome谷歌浏览器中安装插件XPath Helper的方法

    1.首先在以下链接下载XPath Helper插件,链接:https://pan.baidu.com/s/1Ng7HAGgsVfOyqy6dn094Jg 提取码:a1dv 2.插件下载完成后解压,然后 ...

  8. oracle mysql sql 根据一张表更新另一张表

    update CDINFO.Dept_Dict tab1 set PART_FLAG = (select PART_FLAG from DICT.DEPARTMENT_DICT@zyhis4 tab2 ...

  9. 【转】Eclipse快捷键指南

    目录 1 编辑 2 查看 3 窗口 4 导航 5 搜索 6 文本编辑 7 文件 8 项目 9 源代码 10 运行 11 重构 12 修改快捷键 Eclipse快捷键,熟悉快捷键可以帮助开发事半功倍,节 ...

  10. 构造函数以及关键词this

    Java中所有类都有构造方法,用来进行该类对象的初始化,构造方法也有名称,参数和方法体以及访问权限的设定. 1.构造方法的完整定义格式如下: [public|protected|private]< ...