当前位置: 首页 > news >正文

.NET core 自定义过滤器 Filter 实现webapi RestFul 统一接口数据返回格式

之前写过使用自定义返回类的方式来统一接口数据返回格式,.Net Core webapi RestFul 统一接口数据返回格式-CSDN博客

但是这存在一个问题,不是所有接口会按照定义的数据格式返回,除非每个接口都返回我们自定义的类,这种实现起来不太现实。

类似这样,定义一个接口:

返回的只是只有user的json对象:

这显然不是我们想要的结果,我们想要的结果是这样:

{"statusCode": 200,"successful": true,"message": null,"data": {"userId": "001","userName": "小王","password": "123"}
}

我们需要不管接口定义的返回类型是什么,最后的结果都是统一的数据格式,需要实现这个功能就需要自定义一个过滤器来实现。

具体实现代码如下:

自定义一个过滤器类 ResponseWrapperFilter.cs

public class ResponseWrapperFilter : IAsyncResultFilter{public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next){if (context.Result is ObjectResult objectResult){if (objectResult.Value is IApiResponse apiResponse){objectResult.StatusCode = apiResponse.StatusCode;context.HttpContext.Response.StatusCode = apiResponse.StatusCode;}else{var statusCode = objectResult.StatusCode ?? context.HttpContext.Response.StatusCode;var wrapperResp = new ApiResponse<object>{StatusCode = statusCode,Successful = statusCode is >= 200 and < 400,Data = objectResult.Value,};objectResult.Value = wrapperResp;objectResult.DeclaredType = wrapperResp.GetType();}}await next();}}

在代码中进行判断,当响应的类型是 ObjectResult 时,把这个响应结果拿出来,再判断是不是 IApiResponse 类型。

前面我们介绍过,所有 ApiResponse 都实现了 IApiResponse 这个接口,所以可以判断是不是 IApiResponse 类型来确定这个返回结果是否包装过。

没包装的话就给包装一下,就这么简单。

附上 ApiResponse.cs  IApiResponse.cs 代码

    public interface IApiResponse{public int StatusCode { get; set; }public bool Successful { get; set; }public string? Message { get; set; }}public interface IApiResponse<T> : IApiResponse{public T? Data { get; set; }}public interface IApiErrorResponse{public Dictionary<string, object> ErrorData { get; set; }}public class ApiResponse<T> : IApiResponse<T>{public ApiResponse(){}public ApiResponse(T? data){Data = data;}public int StatusCode { get; set; } = 200;public bool Successful { get; set; } = true;public string? Message { get; set; }public T? Data { get; set; }/// <summary>/// 实现将 <see cref="ApiResponse"/> 隐式转换为 <see cref="ApiResponse{T}"/>/// </summary>/// <param name="apiResponse"><see cref="ApiResponse"/></param>public static implicit operator ApiResponse<T>(ApiResponse apiResponse){return new ApiResponse<T>{StatusCode = apiResponse.StatusCode,Successful = apiResponse.Successful,Message = apiResponse.Message};}}public class ApiResponse : IApiResponse, IApiErrorResponse{public int StatusCode { get; set; } = 200;public bool Successful { get; set; } = true;public string? Message { get; set; }public object? Data { get; set; }/// <summary>/// 可序列化的错误/// <para>用于保存模型验证失败的错误信息</para>/// </summary>public Dictionary<string, object>? ErrorData { get; set; }public ApiResponse(){}public ApiResponse(object data){Data = data;}public static ApiResponse NoContent(string message = "NoContent"){return new ApiResponse{StatusCode = StatusCodes.Status204NoContent,Successful = true,Message = message};}public static ApiResponse Ok(string message = "Ok"){return new ApiResponse{StatusCode = StatusCodes.Status200OK,Successful = true,Message = message};}public static ApiResponse Ok(object data, string message = "Ok"){return new ApiResponse{StatusCode = StatusCodes.Status200OK,Successful = true,Message = message,Data = data};}public static ApiResponse Unauthorized(string message = "Unauthorized"){return new ApiResponse{StatusCode = StatusCodes.Status401Unauthorized,Successful = false,Message = message};}public static ApiResponse NotFound(string message = "NotFound"){return new ApiResponse{StatusCode = StatusCodes.Status404NotFound,Successful = false,Message = message};}public static ApiResponse BadRequest(string message = "BadRequest"){return new ApiResponse{StatusCode = StatusCodes.Status400BadRequest,Successful = false,Message = message};}public static ApiResponse BadRequest(ModelStateDictionary modelState, string message = "ModelState is not valid."){return new ApiResponse{StatusCode = StatusCodes.Status400BadRequest,Successful = false,Message = message,ErrorData = new SerializableError(modelState)};}public static ApiResponse Error(string message = "Error", Exception? exception = null){object? data = null;if (exception != null){data = new{exception.Message,exception.Data};}return new ApiResponse{StatusCode = StatusCodes.Status500InternalServerError,Successful = false,Message = message,Data = data};}}

之后在 Program.cs 里注册一下这个过滤器

services.AddControllers(options =>
{options.Filters.Add<ResponseWrapperFilter>();
});

再次调用GetUser接口,可以看到已经包装成统一的数据格式返回了:

而对于之前已经定义返回类型是ApiResponse的接口也不会重复包装:

相关文章:

.NET core 自定义过滤器 Filter 实现webapi RestFul 统一接口数据返回格式

之前写过使用自定义返回类的方式来统一接口数据返回格式&#xff0c;.Net Core webapi RestFul 统一接口数据返回格式-CSDN博客 但是这存在一个问题&#xff0c;不是所有接口会按照定义的数据格式返回&#xff0c;除非每个接口都返回我们自定义的类&#xff0c;这种实现起来不…...

vue3 使用addRoute动态添加路由,页面刷新就白屏解决办法

问题&#xff0c;通过接口动态添加路由&#xff0c;第一次从登录页跳转还是正常的&#xff0c;说明路由添加成功了&#xff0c;但是刷新后就白屏了&#xff0c;且控制台报错路由匹配不到&#xff0c;在项目的main.js&#xff0c;router和路由拦截器中添加了一大堆打印后发现&am…...

探索鸿蒙:了解华为鸿蒙操作系统的基础课程

目录 学习目标&#xff1a; 学习内容&#xff1a; 学习时间&#xff1a; 学习产出&#xff1a; 介绍鸿蒙操作系统的起源和发展历程。 理解鸿蒙操作系统的核心概念和体系结构。 学习如何搭建和配置鸿蒙开发环境。 掌握基础的鸿蒙应用开发技术&#xff0c;包括应用的创建、…...

【Linux】进程周边007之进程控制

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 1.进程创建 2.进程终止 2.…...

【C++】vector容器的模拟实现

目录 一&#xff0c;框架设计 二&#xff0c;构造函数 三&#xff0c;析构函数 四&#xff0c;赋值运算符 五&#xff0c;容器接口的实现 1&#xff0c;迭代器实现 2&#xff0c;“ [] ”运算符的实现 3&#xff0c;swap交换和resize重设大小 4&#xff0c;insert插入…...

华为Harmony——ArkTs语言

文章目录 一、简单示例二、声明式UI描述创建组件无参有参数 配置属性配置事件配置子组件 三、自定义组件基本用法基本结构成员函数/变量 一、简单示例 我们以一个具体的示例来说明ArkTS的基本组成。如下图所示&#xff0c;当开发者点击按钮时&#xff0c;文本内容从“Hello Wo…...

uniapp使用colorUI

colorUI 微动画 | ColorUI 使用文档 1&#xff1a;把colorui里三个文件复制到自己项目中去 App.vue </script> <style> import url(colorui/icon.css); import url(colorui/main.css); import url("colorui/animation.css");-webkit-keyframes show {…...

浅谈测试自动化selenium之POM模式

基于本人也是一个初学者&#xff0c;在运用POM模式的时候记录一下自己的学习笔记。 如果你是大神&#xff0c;那么可以略过&#xff0c;如果你是初学者&#xff0c;希望对你有帮助。 本文阐述了以下几个问题&#xff1a; 什么叫POM模式 为什么要用POM模式 POM模式的思想 POM模…...

什么是事件传播、事件冒泡、事件捕获?

一、事件传播 1、概述 &#xff08;1&#xff09;当事件发生在DOM元素上时&#xff0c;该事件并不完全发生在那个元素 &#xff08;2&#xff09;在冒泡阶段中&#xff0c;事件冒泡或向上传播至父级、祖父级、祖父的父级&#xff0c;直到 window 为止 &#xff08;3&#x…...

【uniapp】uniapp中本地存储sqlite数据库保姆级使用教程(附完整代码和注释)

数据库请求接口封装 uniapp中提供了plus.sqlite接口&#xff0c;在这里我们对常用的数据库请求操作进行了二次封装 这里的dbName、dbPath、recordsTable 可以根据你的需求自己命名 module.exports {/** * type {String} 数据库名称*/dbName: salary,/*** 数据库地址* type {…...

微软推出了GPT-RAG:这是一个机器学习库,为在Azure OpenAI上使用RAG模式生产部署大型语言模型(LLMs)提供了企业级参考架构

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

Centos系统升级gcc版本

自己环境的gcc版本太低&#xff0c;影响使用SAN全家桶进行内存泄露检查 当前环境gcc版本查看 gcc --version 进行升级&#xff1a; 1、安装EPEL存储库 yum install epel-release -y 2、确保系统已经更新到最新版本 yum update -y 3、安装GCC编译器及其相关工具包 yum g…...

Http---HTTP响应报文

1. HTTP响应报文分析 HTTP 响应报文效果图: 响应报文说明: --- 响应行/状态行 --- HTTP/1.1 200 OK # HTTP协议版本 状态码 状态描述 --- 响应头 --- Server: Tengine # 服务器名称 Content-Type: text/html; charsetUTF-8 # 内容类型 Transfer-Encoding: chunked # 发送给客…...

iOS 开发设计 App 上架符合要求的截图

1. 真机运行截屏 2. 可以在 Apple developer 官网 Design 下找到 iPhone 边框 https://developer.apple.com/design/resources/ 不用这个边框也行&#xff0c;可以参考已上架 App 的图片框 3. 使用 Procreate&#xff08;PhotoShop&#xff09;创建符合要求的画布大小 4. 导入…...

DRF之引入

目录 一、web应用模式 【1】前后端混合开发 【2】前后端分离 二、API接口 三、接口测试工具&#xff1a;Postman 四、RESTful API规范 【1】什么是RESTful 【2】RESTful API的规范 2.1 数据的安全保障 2.2 接口特征表现 2.3 多数据版本共存 2.4 数据即是资源&#…...

【Skynet 入门实战练习】事件模块 | 批处理模块 | GM 指令 | 模糊搜索

文章目录 前言事件模块批处理模块GM 指令模块模糊搜索最后 前言 本节完善了项目&#xff0c;实现了事件、批处理、模糊搜索模块、GM 指令模块。 事件模块 什么是事件模块&#xff1f;事件模块是用来在各系统之间传递事件消息的。 为什么需要事件模块&#xff1f;主要目的是…...

Web组态可视化编辑器-by组态

演示地址&#xff1a; http://www.by-lot.com http://www.byzt.net web组态可视化编辑器&#xff1a;引领未来可视化编辑的新潮流 随着网络的普及和快速发展&#xff0c;web组态可视化编辑器应运而生&#xff0c;为人们在网络世界中创建和编辑内容提供了更加便捷的操作方式。这…...

PDF.js介绍以及使用

一、PDF.js是什么 PDF.js是一个JavaScript库&#xff0c;可以在现代Web浏览器中渲染和显示PDF文件。它的主要作用是将PDF文件转换为HTML5格式&#xff0c;以便在浏览器上进行展示和交互。 PDF.js的主要功能包括&#xff1a; 在浏览器中显示PDF&#xff1a;PDF.js使用HTML5的…...

经常使用的排序算法

一、直接插入排序 #include <stdio.h>void insert_sort(int arr[], int n){int i, j, tmp;for (i 1; i < n; i){tmp arr[i];j i - 1;while (j > 0 && arr[j] > tmp){ // 将要插入的元素与数组中的元素比较&#xff08;从后向前比&#xff09;arr[j …...

msyql 24day 数据库主从 主从复制 读写分离 master slave 有数据如何增加

目录 环境介绍读写分离纵向扩展横向扩展 数据库主从准备环境主库环境(master)从库配置(slave)状态分析重新配置问题分析 报错解决从库验证 有数据的情况下 去做主从清理环境环境准备数据库中的锁的机制主库配置从库配置最后给主库解锁常见错误 环境介绍 将一个数据库的数据 复…...

使用 Taro 开发鸿蒙原生应用 —— 探秘适配鸿蒙 ArkTS 的工作原理

背景 在上一篇文章中&#xff0c;我们已经了解到华为即将发布的鸿蒙操作系统纯血版本——鸿蒙 Next&#xff0c;以及各个互联网厂商开展鸿蒙应用开发的消息。其中&#xff0c;Taro作为一个重要的前端开发框架&#xff0c;也积极适配鸿蒙的新一代语言框架 —— ArkTS。 本文将…...

Linux下 自定义多线程并发快速压缩解压缩脚本

文章目录 自定义多线程压缩解压缩脚本使用 Linux下 自定义多线程并发快速压缩解压缩脚本 Linux下常用的tar工具无法支持并行 压缩和解压&#xff0c;对于大量小文件的解压缩&#xff0c;可借助pigz工具实现多线程并行工作&#xff0c;实现更为高效的压缩和解压缩。 自定义多线…...

ubuntu20.04下安装pcl_ubuntu安装pcl

pcl点云数据库&#xff0c;用来进行3D信息的获取与处理&#xff0c;和opencv相比较&#xff0c;opencv是用来处理二维信息&#xff0c;他是学术界与工业界针对点云最全的库&#xff0c;且网络上相关的资料很多。以下是pcl的安装步骤以及遇到的问题。 提前说明&#xff0c;本人…...

阿里云常用配置:日志采集、OSS、RAM 权限策略

文章目录 引言I 日志采集1.1 具体查询语法1.2 查询示例1.3 设置token时间(登录过期时间)II OSS2.1 设置防盗链2.2 验证Referer防盗链是否生效III 通义灵码 (智能编码)IV RAM 权限策略4.1 短信策略4.2 内容风险检测引言 SLS I 日志采集...

回顾丨2023 SpeechHome 第三届语音技术研讨会

下面是整体会议的内容回顾&#xff1a; 18日线上直播回顾 18日上午9:30&#xff0c;AISHELL & SpeechHome CEO卜辉宣布研讨会开始&#xff0c;并简要介绍本次研讨会的筹备情况以及报告内容。随后&#xff0c;CCF语音对话与听觉专委会副主任、清华大学教授郑方&#xff0c…...

【flink】状态清理策略(TTL)

flink的keyed state是有有效期(TTL)的&#xff0c;使用和说明在官网描述的篇幅也比较多&#xff0c;对于三种清理策略没有进行横向对比得很清晰。 全量快照清理(FULL_STATE_SCAN_SNAPSHOT)增量清理(INCREMENTAL_CLEANUP)rocksdb压缩清理(ROCKSDB_COMPACTION_FILTER) 注意&…...

4. 行为模式 - 中介者模式

亦称&#xff1a; 调解人、控制器、Intermediary、Controller、Mediator 意图 中介者模式是一种行为设计模式&#xff0c; 能让你减少对象之间混乱无序的依赖关系。 该模式会限制对象之间的直接交互&#xff0c; 迫使它们通过一个中介者对象进行合作。 问题 假如你有一个创建…...

2015年第四届数学建模国际赛小美赛A题飞机上的细长座椅解题全过程文档及程序

2015年第四届数学建模国际赛小美赛 A题 飞机上的细长座椅 原题再现&#xff1a; 航空公司座位是指在旅途中乘客可以乘坐的座位。一些航空公司现在推出了新的经济舱“超薄”座位。这些座椅除了重量较轻外&#xff0c;理论上还允许航空公司在不显著影响乘客舒适度的情况下增加运…...

机器学习笔记(二)使用paddlepaddle,再探波士顿房价预测

目标 用paddlepaddle来重写之前那个手写的梯度下降方案&#xff0c;简化内容 流程 实际上就做了几个事&#xff1a; 数据准备&#xff1a;将一个批次的数据先转换成nparray格式&#xff0c;再转换成Tensor格式前向计算&#xff1a;将一个批次的样本数据灌入网络中&#xff…...

【Linux】权限篇(二)

权限目录 1. 前言2. 权限2.1 修改权限2.2 有无权限的对比2.3 另外一个修改权限的方法2.3.1 更改用户角色2.3.2 修改文件权限属性 3. 第一个属性列4. 目录权限5. 默认权限 1. 前言 在之前的一篇博客中分享了关于权限的一些知识&#xff0c;这次紧接上次的进行&#xff0c;有需要…...

七牛云储存wordpress/怎么查百度竞价关键词价格

环境要求&#xff1a;必须要有jdk环境,本次讲课使用jdk1.8 结构&#xff1a;一共三个节点(zk服务器集群规模不小于3个节点),要求服务器之间系统时间保持一致。 我这里三个环境IP地址分别是&#xff1a;192.168.128.139&#xff0c;192.168.128.140&#xff0c;192.168.128.141…...

c2c网站的类型/百度推广官方网站

skyline是一款不错的三维编辑浏览软件&#xff0c;官方提供的是英文版&#xff0c;目前还没有汉化包&#xff0c;为了使用方便&#xff0c;我们需要汉化一些简单的对话框&#xff0c;本文介绍如何汉化skyline右键菜单。 首先打开skyline的安装目录&#xff0c;在TerraExplorer …...

惠州营销网站建设/小程序开发公司排行榜

当今的互联网&#xff0c;用户为王。传统的用户单方面接收信息&#xff08;Web 1.0&#xff09;、用户创造信息&#xff08;Web 2.0&#xff09;的爆炸时代已经趋缓&#xff0c;互联网逐步向用户之间交流信息、分享信息的平台发展。如何打造一个优秀的社区&#xff0c;累积有价…...

内网网站建设/中国十大网络销售公司

1. 联合概率密度函数 2. 概率密度的性质 3. 二元连续型随机变量概率分布函数求解示例...

http网站跳转怎么做/专业网络推广公司

PDC(专业开发人员会议)一直是由微软的高级开发者和架构师作为参与者&#xff0c;以便了解未来的微软平台和技术&#xff0c;PDC 2010&#xff0c;您将可以获得关于微软下一代云服务、Windows Phone 7、工具和技术、Internet Explorer 9 和游戏平台的第一手内容&#xff0c;PDC …...

门户网站界面设计/seo是什么地方

题目表述 泰波那契序列 Tn 定义如下&#xff1a; T0 0, T1 1, T2 1, 且在 n > 0 的条件下 Tn3 Tn Tn1 Tn2 给你整数 n&#xff0c;请返回第 n 个泰波那契数 Tn 的值。示例 1&#xff1a; 输入&#xff1a;n 4 输出&#xff1a;4 解释&#xff1a; T_3 0 1 1 2 T…...