asp.net core过滤器应用

筛选器类型

授权筛选器

授权过滤器是过滤器管道的第一个被执行的过滤器,用于系统授权。一般不会编写自定义的授权过滤器,而是配置授权策略或编写自定义授权策略。简单举个例子。

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.AspNetCore.Mvc.Filters;namespace FilterStudy01.Filter
{/// <summary>/// 授权过滤器/// builder.Services.AddMvc(options =>{options.Filters.Add(new WjAuthorizationlFilter());});/// [TypeFilter(typeof(WjAuthorizationlFilter))]可以加在类或者控制器上/// 不登陆的情况下访问/Admin/Index/// </summary>public class WjAuthorizationlFilter : IAuthorizationFilter{public void OnAuthorization(AuthorizationFilterContext context){// 需要排除具有AllowAnymons 这个标签的控制器// 过滤掉带有AllowAnonymousFilterif (HasAllowAnonymous(context)){return;}// 获取当前用户的信息var user = context.HttpContext.User;// 自定义的授权检查逻辑if (user == null || user?.Identity?.IsAuthenticated != true){// 如果检查不通过,设置 Result 属性为一个 IActionResult 对象,可以阻止请求进一步被处理context.Result = new ForbidResult();}}// 判断是否含有IAllowAnonymousprivate bool HasAllowAnonymous(AuthorizationFilterContext context){if (context.Filters.Any(filter => filter is IAllowAnonymousFilter)){return true;}// 终节点:里面包含了路由方法的所有元素信息(特性等信息)var endpoint = context.HttpContext.GetEndpoint();return endpoint?.Metadata.GetMetadata<IAllowAnonymous>() != null;}}
}

https://zhuanlan.zhihu.com/p/677748480
https://blog.csdn.net/qq_41942413/article/details/135163599
https://learn.microsoft.com/zh-cn/aspnet/core/security/authorization/simple?view=aspnetcore-9.0

IP过滤器,不过这个可以放到Action过滤器中,看需求,如果全部限制可以放授权筛选器,也可以简单的做个ip黑名单和白名单

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;namespace FilterStudy01.Filter
{/// <summary>/// 实现ip过滤器/// </summary>public class WjlIpAuthorizationFilter : IAuthorizationFilter{public void OnAuthorization(AuthorizationFilterContext context){var allowIps = new List<string>(){"127.0.0.1"};var requestIp = context?.HttpContext?.Connection?.RemoteIpAddress?.ToString() ?? "";if (!allowIps.Contains(requestIp)){var result = new{Success = false,Msg = "非法请求"};if (context != null){context.Result = new JsonResult(result);}}}}
}

资源筛选器

资源过滤器,在授权过滤器执行后执行,该过滤器包含“之前”和“之后”两个行为,包裹了模型绑定、操作过滤器、Action执行、异常过滤器、结果过滤器以及结果执行。
缓存结果提高网站的响应速度,缓存后,就可以直接从内存中直接取数据,而无需在执行方法。

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;namespace FilterStudy01.Filter
{/// <summary>/// 资源过滤器实现缓存/// IAsyncResourceFilter/// 如果继承Attribute 使用方式如下[WjlResouerceFilter]/// 如何不继承 builder.Services.AddMvc(options =>{options.Filters.Add(new WjlResouerceFilter());});/// </summary>public class WjlResouerceFilterAttribute : Attribute, IResourceFilter{private static readonly Dictionary<string, IActionResult?> dic = new Dictionary<string, IActionResult?>();/// <summary>/// 方法执行之后/// </summary>/// <param name="context"></param>public void OnResourceExecuted(ResourceExecutedContext context){var path = context.HttpContext.Request.Path;dic[path] = context?.Result;}/// <summary>/// 方法执行之前/// </summary>/// <param name="context"></param>public void OnResourceExecuting(ResourceExecutingContext context){var path = context.HttpContext.Request.Path;if (dic.ContainsKey(path)){context.Result = dic[path];}}}
}

操作筛选器

操作过滤器,在模型绑定后执行,该过滤器同样包含“之前”和“之后”两个行为,包裹了Action的执行(不包含Controller的创建)。如果Action执行过程中或后续操作过滤器中抛出异常,首先捕获到异常的是操作过滤器的OnActionExecuted,而不是异常过滤器。
案例:接口访问日志记录,完整的日志记录方便跟踪分析问题以及攻击

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Primitives;
using System.Diagnostics;
using System.Dynamic;
using System.Text;
using System.Text.Json;namespace FilterStudy01.Filter
{/// <summary>/// 操作过滤器/// builder.Services.AddMvc(options =>{options.Filters.Add(new WjlAsyncActionFilter());});/// </summary>public class WjlAsyncActionFilter : IAsyncActionFilter{/// <summary>/// 记录请求日志,方便跟踪以及预警/// 需要开启Buffer/// app.Use(next => new RequestDelegate(async context => {context.Request.EnableBuffering();await next(context);}));/// </summary>/// <param name="context"></param>/// <param name="next"></param>/// <returns></returns>public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next){dynamic model = new ExpandoObject();var httpContext = context.HttpContext;var name = context.ActionDescriptor.DisplayName;var actionName = context.ActionDescriptor.RouteValues["action"] ?? ""; //action名字var controllerName = context.ActionDescriptor.RouteValues["controller"] ?? ""; //controller名字var queryStrings = httpContext.Request.QueryString; //GET请求的后缀var fromString = new StringBuilder();if (httpContext.Request.HasFormContentType){var forms = httpContext.Request?.Form; //Form表单请求if (forms != null){foreach (var item in forms){fromString.Append($"{item.Key}={item.Value}");}}}var ipAddress = httpContext?.Connection?.RemoteIpAddress?.ToString();string body = "";StringValues authHeader = "";if (httpContext != null && httpContext.Request != null){if (httpContext.Request.Body != null){httpContext.Request.Body.Position = 0;//读取请求体var sr = new System.IO.StreamReader(httpContext.Request.Body);body = await sr.ReadToEndAsync(); //请求体内容httpContext.Request.Body.Position = 0;}httpContext.Request.Headers.TryGetValue("Authorization", out authHeader);}//赋值model.Headers = authHeader;model.RequestBody = body;model.IPAddress = ipAddress;model.Result = "";model.FormString = fromString.ToString();model.QueryString = queryStrings;model.Action = actionName;model.ActionClassName = name;model.Controller = controllerName;var stopWatch = Stopwatch.StartNew();stopWatch.Reset();await next();stopWatch.Stop();var customerTime = Math.Round(stopWatch?.Elapsed.TotalMilliseconds ?? 0, 2);//ObjectResult、JsonResult、ViewResult、LocalRedirectResult//RedirectResult、RedirectToActionResult、BadRequestResult、BadRequestObjectResult//OkResult OkObjectResult NoContentResult NotFoundResult ForbiddenResult//ChallengeResult StatusCodeResult ObjectResult FileResult(FileContentResult、FilePathResult、FileStreamResult、VirtualFileResult)//ContentResult EmptyResult ActionResult(基类不能直接用)//上面是全部的类型按照需要自己处理var fileresult = context.Result as FileResult;if (fileresult == null){var result = context.Result as ObjectResult;var resValue = result?.Value;if (result != null && resValue != null){model.Result = JsonSerializer.Serialize(resValue);}}else{model.Result = "文件下载";}Console.WriteLine(JsonSerializer.Serialize(model));}}
}

异常筛选器

监听全局异常并统一格式返回
在这里插入图片描述

在这里插入图片描述

using FilterStudy01.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Text;namespace FilterStudy01.Filter
{/// <summary>///  使用///  builder.Services.AddMvc(options =>{options.Filters.Add(new WjlExceptionFilter());});///  并不是所有的异常都捕获,比如mvc中razor页面报错不能捕获///  可以捕获Controller创建时(也就是只捕获构造函数中抛出的异常)、模型绑定、Action Filter和Action中抛出的未处理异常///  其他异常不会捕获,可以使用中间件/// </summary>public class WjlExceptionFilter : IAsyncExceptionFilter{/// <summary>/// 获取异常的详细信息/// </summary>/// <param name="ex"></param>/// <returns></returns>private string GetExceptionDetails(Exception ex){if (ex == null){return string.Empty;}StringBuilder sb = new StringBuilder();sb.Append("异常消息: ");sb.Append(ex.Message);sb.Append("\n");sb.Append("堆栈跟踪: ");sb.Append(ex.StackTrace);// 递归获取内部异常的详细信息  if (ex.InnerException != null){sb.Append(GetExceptionDetails(ex.InnerException));}return sb.ToString();}/// <summary>/// 出现异常时触发/// </summary>/// <param name="context"></param>/// <returns></returns>public async Task OnExceptionAsync(ExceptionContext context){// 如果异常没有被处理则进行处理if (context.ExceptionHandled == false){var httpContext = context.HttpContext;//action名字var actionName = context.ActionDescriptor.RouteValues["action"] ?? "";//controller名字var controllerName =context.ActionDescriptor.RouteValues["controller"] ?? "";var path = httpContext.Request.Path;//这里要替换成日志Console.WriteLine(GetExceptionDetails(context.Exception));CommonResult commonResult = new CommonResult();commonResult.ResultNo = 1;commonResult.ResultData = "server error";context.Result = new JsonResult(commonResult);}// 设置为true,表示异常已经被处理了context.ExceptionHandled = true;}}
}using FilterStudy01.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Text;namespace FilterStudy01.Filter
{/// <summary>/// 局部使用///  [WjlExceptionFilter]/// </summary>public class WjlExceptionFilterAttribute : ExceptionFilterAttribute{/// <summary>/// 获取异常的详细信息/// </summary>/// <param name="ex"></param>/// <returns></returns>private string GetExceptionDetails(Exception ex){if (ex == null){return string.Empty;}StringBuilder sb = new StringBuilder();sb.Append("异常消息: ");sb.Append(ex.Message);sb.Append("\n");sb.Append("堆栈跟踪: ");sb.Append(ex.StackTrace);// 递归获取内部异常的详细信息  if (ex.InnerException != null){sb.Append(GetExceptionDetails(ex.InnerException));}return sb.ToString();}public override async Task OnExceptionAsync(ExceptionContext context){// 如果异常没有被处理则进行处理if (context.ExceptionHandled == false){var httpContext = context.HttpContext;//action名字var actionName = context.ActionDescriptor.RouteValues["action"] ?? "";//controller名字var controllerName =context.ActionDescriptor.RouteValues["controller"] ?? "";var path = httpContext.Request.Path;//这里要替换成日志Console.WriteLine(GetExceptionDetails(context.Exception));CommonResult commonResult = new CommonResult();commonResult.ResultNo = 1;commonResult.ResultData = "服务器开小差了";context.Result = new JsonResult(commonResult);}// 设置为true,表示异常已经被处理了context.ExceptionHandled = true;}}
}

结果筛选器

对返回的结果封装,统一结果返回

using FilterStudy01.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;namespace FilterStudy01.Filter
{/// <summary>/// 全局使用/// </summary>public class WjlResultFilter : IResultFilter{/*使用builder.Services.AddMvc(options =>{options.Filters.Add(new WjlResultFilter());});*/public void OnResultExecuted(ResultExecutedContext context){}public void OnResultExecuting(ResultExecutingContext context){//ObjectResult、JsonResult、ViewResult、LocalRedirectResult//RedirectResult、RedirectToActionResult、BadRequestResult、BadRequestObjectResult//OkResult OkObjectResult NoContentResult NotFoundResult ForbiddenResult//ChallengeResult StatusCodeResult ObjectResult FileResult(FileContentResult、FilePathResult、FileStreamResult、VirtualFileResult)//ContentResult EmptyResult ActionResult(基类不能直接用)var jsonResult = context.Result as JsonResult;if (jsonResult != null && jsonResult.Value != null){//1、只能拦截JsonResultCommonResult commonResult = new CommonResult();commonResult.ResultNo = 0;commonResult.ResultData = jsonResult.Value;jsonResult.Value = commonResult;}}}
}using FilterStudy01.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;namespace FilterStudy01.Filter
{/// <summary>/// 局部使用/// </summary>public class WjlResultFilterAttribute : ResultFilterAttribute{public override void OnResultExecuting(ResultExecutingContext context){var jsonResult = context.Result as JsonResult;if (jsonResult != null && jsonResult.Value != null){//1、只能拦截JsonResultCommonResult commonResult = new CommonResult();commonResult.ResultNo = 0;commonResult.ResultData = jsonResult.Value;jsonResult.Value = commonResult;}}}
}

筛选器接口的同步和异步版本任意实现一个,而不是同时实现 。 运行时会先查看筛选器是否实现了异步接口,如果是,则调用该接口。 如果不是,则调用同步接口的方法。 如果在一个类中同时实现异步和同步接口,则仅调用异步方法。 使用抽象类(如 ActionFilterAttribute)时,将为每种筛选器类型仅重写同步方法或仅重写异步方法。

大佬总结的图示

参考

授权过滤器
https://learn.microsoft.com/zh-cn/aspnet/core/mvc/controllers/filters?view=aspnetcore-8.0
https://blog.csdn.net/sD7O95O/article/details/119223675
Razor页面筛选器
异常过滤器理解
错误处理
过滤器应用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/888331.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux DNS解释器

作用 DNS&#xff08;Domain Name System&#xff09;是互联网上的一项服务&#xff0c;用于将域名和IP地址进行相互映射&#xff0c;使人 更方便的访问互联网 正向解析&#xff1a;域名->IP 反向解析&#xff1a;IP->域名 连接方式 DNS使用53端口监听网络 查看方法&a…

3.STM32通信接口之SPI通信---SPI实战(W25Q64存储模块介绍)《精讲》

上一节介绍了SPI的通信过程和方法&#xff0c;接下来就要进行STM32与外围模块通信了&#xff0c;这个模块是一块非易失型存储芯片&#xff0c;能够提供8MB的存储空间。接下来跟着Whappy脚步&#xff0c;进行探索新大陆吧&#xff01;【免费】W25Q64(中英文数据手册)资源-CSDN文…

嵌入式系统应用-LVGL的应用-平衡球游戏 part2

平衡球游戏 part2 4 mpu60504.1 mpu6050 介绍4.2 电路图4.3 驱动代码编写 5 游戏界面移植5.1 移植源文件5.2 添加头文件 6 参数移植6.1 4 mpu6050 4.1 mpu6050 介绍 MPU6050是一款由InvenSense公司生产的加速度计和陀螺仪传感器&#xff0c;广泛应用于消费电子、机器人等领域…

java将word docx pdf转换为图片(不需要额外下载压缩包,直接导入maven坐标)

(本代码实现的是将第1页转为图片&#xff0c;主要用于制作文件缩略图) pdf转图片容易 docx转图片麻烦&#xff0c;看其他博客可以直接导入maven坐标&#xff0c;但我知道那是需要付费且有时限的包 本着简单实用的心&#xff0c;我找到法子了 pdf转图片&#xff1a;有库直接转…

C#学写了一个程序记录日志的方法(Log类)

1.错误和警告信息单独生产文本进行记录&#xff1b; 2.日志到一定内存阈值可以打包压缩&#xff0c;单独存储起来&#xff0c;修改字段MaxLogFileSizeForCompress的值即可&#xff1b; 3.Log类调用举例&#xff1a;Log.Txt(JB.信息,“日志记录内容”,"通道1"); usi…

linux(centos) 环境部署,安装JDK,docker(mysql, redis,nginx,minio,nacos)

目录 1.安装JDK (非docker)1.1 将文件放在目录下&#xff1a; /usr/local/jdk1.2 解压至当前目录1.3 配置环境变量 2.安装docker2.1 验证centos内核2.2 安装软件工具包2.3 设置yum源2.4 查看仓库中所有docker版本&#xff0c;按需选择安装2.5 安装docker2.6 启动docker 并 开机…

电阻改善信号完整性

1.为什么电路端接电阻能改善信号完整性 由于电信号在PCB上传输&#xff0c;因此在PCB设计中可以把PCB走线认为是信号的通道&#xff0c;当该通道的 物理结构&#xff08;线宽&#xff0c;线到参考面的距离等&#xff09;发生变化&#xff0c;特别是有一些突变时&#xff0c;都会…

Java基础面试题,46道Java基础八股文(4.8万字,30+手绘图)

Java是一种广泛使用的编程语言&#xff0c;由Sun Microsystems&#xff08;现为Oracle Corporation的一部分&#xff09;在1995年首次发布。它是一种面向对象的语言&#xff0c;这意味着它支持通过类和对象的概念来构造程序。 Java设计有一个核心理念&#xff1a;“编写一次&am…

记录下nginx接口代理配置问题

其中api和api1是前面定义的upstream&#xff0c;ip相同只是端口不同。 一开始/api1/直接 像api一样 proxy_pass http://api1这样是不行的&#xff0c;因为会代理到 后端的 /api1/...接口&#xff0c;而后端实际接口地址是 /api/..... 所以必须像上面写法才能将外网的 /api…

高效流程图绘制:开发设计流程图利器

在选择画流程图的工具时&#xff0c;不同的项目和使用场景会决定最佳的工具。以下是几款常见的流程图工具&#xff0c;并结合具体项目使用场景提供建议&#xff1a; 1. Lucidchart 特点&#xff1a; 在线协作&#xff1a;支持多人实时协作&#xff0c;适合团队合作。模板丰富&…

【Python网络爬虫笔记】7-网络爬虫的搜索工具re模块

目录 一、网络爬虫中的正则表达式和re模块&#xff08;一&#xff09;数据提取的精确性&#xff08;二&#xff09;处理复杂的文本结构&#xff08;三&#xff09;提高数据处理效率 二、正则表达式的内涵&#xff08;一&#xff09;、常用元字符&#xff08;二&#xff09;、量…

Day4:生信新手笔记 — R语言简单命令与Rstudio配置

一、Rstudio的界面展示 (很像Matlab风格) 二、Rstudio设置字体大小 三、 用Rproject管理工作目录 工作目录(working directory) 即当前所在的目录&#xff0c;是脚本、图片、文件的默认保存位置&#xff0c;也是文件读取的默认位置。R语言只能和一个文件夹进行互动&#xff0…

koa中间件

文章目录 1. koa中间件简介2. 中间件类型1. 应用级中间件2. 路由级中间件3. 错误处理中间件4. 第三方中间件 3.中间件执行流程 1. koa中间件简介 在Koa中&#xff0c;中间件呈现为一个异步函数&#xff0c;该函数支持 async/await 语法&#xff0c;它接收两个参数&#xff1a;…

【开源】A060-基于Spring Boot的游戏交易系统的设计与实现

&#x1f64a;作者简介&#xff1a;在校研究生&#xff0c;拥有计算机专业的研究生开发团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看项目链接获取⬇️&#xff0c;记得注明来意哦~&#x1f339; 赠送计算机毕业设计600个选题ex…

泷羽sec:shell编程(9)不同脚本的互相调用和重定向操作

声明&#xff1a; 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&#…

Pod Pending无法调度

根据您提供的Kubernetes调度警告信息&#xff0c;以下是可能的原因分析&#xff1a; Insufficient Memory: 有1个节点因为内存不足而无法调度Pod。这可能是因为该节点上已经运行的Pod消耗了大量内存&#xff0c;没有足够的资源来运行新的Pod。 Pod Affinity/Anti-Affinity: 有…

QT 左右 上下,拉伸 分配窗口大小

要的效果是以下&#xff1a; QT C 两个QWideget A B现在有放在一个窗口QWideget Test内&#xff0c;初始比例要2&#xff1a;8 ,现在我要 A B 两个窗口中间 当鼠标移到他中间时&#xff0c;有条线&#xff0c;可以左右移动来控件 A B 窗口所占的大小widgetB &#xff08;有 wi…

pyqt6简单应用

from PyQt6.QtWidgets import QWidget,QPushButton,QLineEdit,QLabel,QApplication from PyQt6.QtGui import QPixmap,QIcon,QCursor from PyQt6.QtCore import Qt from PyQt6 import QtCoreimport sysclass Ui_window(QWidget):def __init__(self):super().__init__()# 设置窗…

【Spring篇】初始Spring MVC框架之Spring MVC入门程序编写

&#x1f9f8;安清h&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;【计算机网络】【Mybatis篇】【Spring篇】 &#x1f6a6;作者简介&#xff1a;一个有趣爱睡觉的intp&#xff0c;期待和更多人分享自己所学知识的真诚大学生。 目录 &#x1f3af;Spring MVC概述 …

祖先序列重建结合机器学习改进双键还原酶-文献精读87

Ancestral Sequence Reconstruction Meets Machine Learning: Ene Reductase Thermostabilization Yields Enzymes with Improved Reactivity Profiles 祖先序列重建结合机器学习&#xff1a;酶还原酶热稳定化产生具有改进反应性特征的酶 摘要 烯还原酶&#xff08;EREDs&…