文章目录

  • 前言
  • 一、全局过滤
    • 1.全局行为过滤的概念
    • 2.全局行为过滤的注册方式
      • 2.1 方法注册
      • 2.2 控制器注册
      • 2.3 全局注册
      • 2.4 TypeFilter 和 ServiceFilter 注册方式
    • 3.案例
  • 二、中间件
    • 1.跨域中间件
    • 2.全局异常中间件
    • 三、格式化配置

前言

本文主要讲解程序得全局配置,主要包含内容有

  • 全局过滤
  • 中间件
  • 格式化配置

一、全局过滤

1.全局行为过滤的概念

.NET Core提供了5大过滤器供我们用来处理请求前后需要执行的代码。

  • Authentication Filter(授权过滤器):授权过滤器最先运行,用于确定是否已针对请求为用户授权。 如果请求未获授权,授权过滤器可以让管道短路。
public class AuthonizationFilter :Attribute,IAuthorizationFilter{public void OnAuthorization(AuthorizationFilterContext context){//这里可以做复杂的权限控制操作if (context.HttpContext.User.Identity.Name != "1") //简单的做一个示范{//未通过验证则跳转到无权限提示页RedirectToActionResult content = new RedirectToActionResult("NoAuth", "Exception", null);context.Result = content;}}}
  • Resource Filter(资源过滤器):可以通过Resource Filter 进行资源缓存、防盗链等操作。 使用Resource Filter 要求实现IResourceFilter 抽象接口。
public class ResourceFilter : Attribute,IResourceFilter
{public void OnResourceExecuted(ResourceExecutedContext context){// 执行完后的操作}public void OnResourceExecuting(ResourceExecutingContext context){// 执行中的过滤器管道}
}
  • ActionFilter(操作过滤器):可以通过ActionFilter 拦截 每个执行的方法进行一系列的操作,比如:执行操作日志、参数验证,权限控制 等一系列操作。
public class ActionFilter : Attribute, IActionFilter{public void OnActionExecuted(ActionExecutedContext context){//执行完成....}public void OnActionExecuting(ActionExecutingContext context){//执行中...}}
  • ExceptionFilter(异常过滤器):可以进行全局的异常日志收集 等操作。
public class ExecptionFilter : Attribute, IExceptionFilter{private ILogger<ExecptionFilter> _logger;//构造注入日志组件public ExecptionFilter(ILogger<ExecptionFilter> logger){_logger = logger;}public void OnException(ExceptionContext context){//日志收集_logger.LogError(context.Exception, context?.Exception?.Message??"异常");}}
  • ResultFilter(结果过滤器):结果过滤器,可以对结果进行格式化、大小写转换等一系列操作。
public class ResultFilter : Attribute, IResultFilter{public void OnResultExecuted(ResultExecutedContext context){ // 在结果执行之后调用的操作...}public void OnResultExecuting(ResultExecutingContext context){// 在结果执行之前调用的一系列操作}}

2.全局行为过滤的注册方式

2.1 方法注册

[AuthonizationFilter()]
public IActionResult Index()
{}

2.2 控制器注册

[AuthonizationFilter()]
public class FirstController : Controller
{private ILogger<FirstController> _logger;public FirstController(ILogger<FirstController> logger){_logger = logger;}public IActionResult Index(){return View();}
}

2.3 全局注册

public void ConfigureServices(IServiceCollection services)
{//全局注册异常过滤器services.AddControllersWithViews(option=> {option.Filters.Add<ExecptionFilter>();});
}

2.4 TypeFilter 和 ServiceFilter 注册方式

ServiceFilter 我们必须在 Startup.cs 中注册.TypeFilter 由 Microsoft.Extensions.DependencyInjection.ObjectFactory 注入,我们不需要注册该过滤器。

1、ServiceFilter

//注入一个ServiceFilter
builder.Services.AddScoped<LoggingResponseHeaderFilterService>();
[ServiceFilter(typeof(LoggingResponseHeaderFilterService))]
public IActionResult WithServiceFilter() =>Content($"- {nameof(FilterDependenciesController)}.{nameof(WithServiceFilter)}");

2、TypeFilter

[TypeFilter(typeof(LoggingResponseHeaderFilter),Arguments = new object[] { "Filter-Header", "Filter Value" })]
public IActionResult WithTypeFilter() =>Content($"- {nameof(FilterDependenciesController)}.{nameof(WithTypeFilter)}");

3.案例

services.AddControllers(c =>
{c.Filters.Add(typeof(ViewModelActionFiter));c.MaxModelValidationErrors = 99999;
}).ConfigureApiBehaviorOptions(o =>
{//.Net Core 禁用模型验证过滤器o.SuppressModelStateInvalidFilter = true;
})


ViewModelActionFiter相关代码

/// <summary>
/// ViewModelActionFiter
/// </summary>
public class ViewModelActionFiter : ActionFilterAttribute
{/// <summary>/// override OnActionExecuting/// </summary>/// <param name="context">context</param>public override void OnActionExecuting(ActionExecutingContext context){//模型校验失败处理的函数if (!context.ModelState.IsValid){string method = context.HttpContext.Request.Method;ResultModel<object> result = new ResultModel<object>();StringBuilder msg = new StringBuilder();bool flag = false;foreach (var item in context.ModelState.Values){if (method.Equals("GET")){msg.Append($",parameter value“{item.AttemptedValue}”does not pass the verification!");}else{foreach (var error in item.Errors){if (error.ErrorMessage.Contains("convert")|| error.ErrorMessage.Contains("Unexpected character")|| error.ErrorMessage.Contains("is not")|| error.ErrorMessage.Contains("valid")|| error.ErrorMessage.Contains("Input ")){flag = true;}else{msg.Append($",{error.ErrorMessage}");}}}}if (flag){msg.Append($",The data is of incorrect type or the value exceeds the type range");}if (msg.ToString().Length > 0){result.ErrorMessage += msg.ToString().Substring(1);}result.Code = 400;context.Result = new JsonResult(result, new Newtonsoft.Json.JsonSerializerSettings(){ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver(),Formatting = Newtonsoft.Json.Formatting.Indented,DateFormatString = "yyyy-MM-dd HH:mm:ss"});}else{base.OnActionExecuting(context);}}
}

二、中间件

注入中间件

app.UseMiddleware<ModernWMS.Core.Middleware.CorsMiddleware>();
app.UseMiddleware<GlobalExceptionMiddleware>();

1.跨域中间件

public class CorsMiddleware
{#region parameter/// <summary>/// agent/// </summary>private readonly RequestDelegate _next;#endregion#region Constructor/// <summary>/// Constructor/// </summary>/// <param name="next">Delegate in next step</param>public CorsMiddleware(RequestDelegate next){_next = next;}#endregion/// <summary>/// Invoke/// </summary>/// <param name="httpContext">httpContext</param>/// <returns></returns>public Task Invoke(HttpContext httpContext){if (httpContext.Request.Method == "OPTIONS"){httpContext.Response.Headers.Add("Access-Control-Allow-Origin", httpContext.Request.Headers["Origin"]);httpContext.Response.Headers.Add("Access-Control-Allow-Headers", httpContext.Request.Headers["Access-Control-Request-Headers"]);httpContext.Response.Headers.Add("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS,HEAD,PATCH");httpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true");httpContext.Response.Headers.Add("Access-Control-Max-Age", "86400");httpContext.Response.StatusCode = StatusCodes.Status200OK;return Task.CompletedTask;}if (httpContext.Request.Headers["Origin"] != ""){httpContext.Response.Headers.Add("Access-Control-Allow-Origin", httpContext.Request.Headers["Origin"]);}httpContext.Response.Headers.Add("Access-Control-Allow-Headers", httpContext.Request.Headers["Access-Control-Request-Headers"]);httpContext.Response.Headers.Add("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS,HEAD,PATCH");httpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true");httpContext.Response.Headers.Add("Access-Control-Max-Age", "86400");return _next.Invoke(httpContext);}}

2.全局异常中间件

/// <summary>
/// Global exception middleware
/// </summary>
public class GlobalExceptionMiddleware
{#region parameterprivate readonly RequestDelegate next; private readonly ILogger<GlobalExceptionMiddleware> logger;/// <summary>/// Localizer Service/// </summary>private readonly IStringLocalizer<MultiLanguage> _stringLocalizer;#endregion#region Constructor/// <summary>/// Constructor/// </summary>/// <param name="next">Delegate in next step</param>/// <param name="logger">log manager</param>/// <param name="stringLocalizer">Localizer</param>public GlobalExceptionMiddleware(RequestDelegate next,ILogger<GlobalExceptionMiddleware> logger,IStringLocalizer<MultiLanguage> stringLocalizer){this.next = next;this.logger = logger;this._stringLocalizer = stringLocalizer;}#endregion/// <summary>/// invoke/// </summary>/// <param name="context">httpcontext</param>/// <returns></returns>public async Task Invoke(HttpContext context){try{await next.Invoke(context);}catch (Exception ex){await WriteExceptionAsync(context, ex);}}/// <summary>/// Write Log/// </summary>/// <param name="context">httpcontext</param>/// <param name="e">error messasge</param>/// <returns></returns>private async Task WriteExceptionAsync(HttpContext context, Exception e){if (e != null){var response = context.Response;var message = e.InnerException == null ? e.Message : e.InnerException.Message;response.ContentType = "application/json";var ip = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();if (string.IsNullOrEmpty(ip)){ip = context.Connection.RemoteIpAddress.ToString();}logger.LogError($"\r\n\r\nIP:{ip},Exception:{e.Message}\r\nStackTrace:{e.StackTrace}");string result = Utility.JsonHelper.SerializeObject(ResultModel<object>.Error(_stringLocalizer["operation_failed"]));await context.Response.WriteAsync(result).ConfigureAwait(false);}else{var code = context.Response.StatusCode;switch (code){case 200:return;case 204:return;case 401:context.Response.ContentType = "application/json";await context.Response.WriteAsync(Utility.JsonHelper.SerializeObject(ResultModel<object>.Error("Invalid Token"))).ConfigureAwait(false);break;default:context.Response.ContentType = "application/json";await context.Response.WriteAsync(Utility.JsonHelper.SerializeObject(ResultModel<object>.Error("Unknown Error"))).ConfigureAwait(false);break;}}}}

三、格式化配置

.Net Core WebApi中输出格式几乎都是json,但是在core中使用任何服务都需要配置,这里需要配置 AddNewtonsoftJson

services.AddControllers().AddNewtonsoftJson(options =>{//修改属性名称的序列化方式,首字母小写,即驼峰样式options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();//日期类型默认格式化处理 方式1options.SerializerSettings.Converters.Add(new IsoDateTimeConverter(){DateTimeFormat = "yyyy/MM/dd HH:mm:ss"});//日期类型默认格式化处理 方式2options.SerializerSettings.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;options.SerializerSettings.DateFormatString = "yyyy/MM/dd HH:mm:ss";//忽略循环引用options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;//解决命名不一致问题 options.SerializerSettings.ContractResolver = new DefaultContractResolver();//空值处理options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
});

可以参考微软官方文档:https://learn.microsoft.com/zh-cn/aspnet/core/web-api/advanced/formatting?view=aspnetcore-7.0

【愚公系列】2023年02月 WMS智能仓储系统-010.全局过滤、中间件、格式化配置相关推荐

  1. 【愚公系列】2023年02月 WMS智能仓储系统-011.数据库文档设计

    文章目录 前言 一.数据库文档设计 1.chm版本 2.PDF版本 3.html版本 二.数据库表目录 表结构 __EFMigrationsHistory asn asnsort category c ...

  2. 【愚公系列】2023年02月 WMS智能仓储系统-018.收获管理和发货管理(完结篇)

    文章目录 前言 一.收获管理和发货管理 1.收获管理 1.1 页面代码 1.2 接口代码 2.发货管理 1.1 页面代码 1.2 接口代码 前言 WMS智能仓储收货管理和发货管理是非常重要的两个功能 ...

  3. 【愚公系列】2023年02月 WMS智能仓储系统-007.Swagger接口文档的配置

    文章目录 前言 一.Swagger接口文档的配置 1.安装包 2.注入 2.1 Swagger服务的注入 2.2 appsetting.json的配置 2.3 Swagger服务的封装 2.3.1 S ...

  4. 【愚公系列】2023年02月 WMS智能仓储系统-017.仓内作业(库存冻结、库存调整、库存盘点)

    文章目录 前言 一.仓内作业 1.库存冻结 1.1 页面代码 1.2 接口代码 2.库存调整 2.1 页面代码 2.2 接口代码 3.库存盘点 3.1 页面代码 3.2 接口代码 前言 这节主要分为两 ...

  5. 【愚公系列】2023年02月 WMS智能仓储系统-016.库存管理和仓内作业(库存管理、仓内加工、库存移动)

    文章目录 前言 一.库存管理 1.1 页面代码 1.2 接口代码 二.仓内作业 1.仓内加工 1.1 页面代码 1.2 接口代码 2.库存移动 2.1 页面代码 2.2 接口代码 前言 这节主要分为两 ...

  6. 【愚公系列】2023年02月 WMS智能仓储系统-001.NLog日志的使用

    文章目录 前言 一.NLog日志的使用 1.安装包 2.配置文件nlog.config 3.使用 前言 系统日志是记录系统中硬件.软件和系统问题的信息,同时还可以监视系统中发生的事件.用户可以通过它来 ...

  7. 【愚公系列】2023年02月 WMS智能仓储系统-012.登录功能的实现

    文章目录 前言 1.业务流程说明 2.登录业务的相关技术点 3.登录-token原理分析 4.前端框架设计 一.登录功能的实现 1.登录页面设计 2.登录逻辑功能实现 2.1 登录逻辑页面 2.2 接 ...

  8. 【愚公系列】2023年02月 WMS智能仓储系统-015.基础设置(货主信息、运费设置、客户信息)

    文章目录 前言 一.基础设置 1.货主信息 1.1 页面代码 1.2 接口代码 2.运费设置 2.1 页面代码 2.2 接口代码 3.客户信息 3.1 页面代码 3.2 接口代码 前言 基础设置主要分 ...

  9. 【愚公系列】2023年02月 WMS智能仓储系统-006.租户功能的配置

    文章目录 前言 一.租户功能的配置 1.注入租户类 2.相关类说明 前言 多租户技术(英语:multi-tenancy technology)或称多重租赁技术,是一种软件架构技术,它是在探讨与实现如何 ...

最新文章

  1. cocos2d-x JS 开启远程代码调试
  2. svn服务器如何导入导出文件,如何导入svn dump备份文件或源代码文件?
  3. 为何 epoll 的 ET 模式一定要设置为非阻塞IO
  4. Django新建项目
  5. 如何找到 SAP Spartacus OCC cms page 发送请求时读取 API endpoint 的代码
  6. python添加环境变量_windows系统下python学习-1 (python环境变量配置)
  7. c语言传递多个参数给线程,关于ssl多线程参数的传递
  8. 美女面试官问我Python如何优雅的创建临时文件,我的回答....
  9. 肚子上挂张画就能隐身:AI完全看不出我在哪,更看不出我是人类了 | 开源
  10. 蓝桥杯 PREV-3 历届试题 带分数 Java版
  11. 使用ZooKeeper ACL特性进行znode控制
  12. python可视化编程软件下载_mPython-mPython(图形化编程软件)下载 v0.5.0官方版-下载啦...
  13. matlab 正交特征向量,关于左右特征向量的正交性问题 求助!!!!
  14. 响应式垂直时间轴js特效插件 带动画效果
  15. TestBird《2021中国手游测试白皮书》---国内手游
  16. 海康摄像头二次开发python_海康摄像头的二次开发(java)
  17. python开发his系统_医院HIS系统调用钉钉开放平台的简单实例
  18. day37--十字链表
  19. Wannafly挑战赛26 B 冥土追魂
  20. 王芷蕾、天韵诗班-给我换颗心(心灵不打烊)

热门文章

  1. 1024 致敬程序员
  2. 分享支持一站式查快递单号查询物流信息
  3. 基于 arduino 的两轮自行车
  4. laravel excel 导出
  5. COM Interop入门
  6. 科技云报道:FONE:半年融资过亿元,打造EPM领域“最强国货”
  7. POCO中的异常处理和调试
  8. CSS3实现扇形动画菜单特效
  9. ATM和电路交换和分组交换区别
  10. python画笑脸表情_用Matplotlib,妈妈再也不担心我没有表情包斗图了