.Net Core webapi RestFul 统一接口数据返回格式

在RestFul风格盛行的年代,大部分接口都需要一套统一的数据返回格式,那么我们怎么才能保证使用统一的json数据格式返回呢,下面给大家简单介绍一下:

假如我们需要接口统一返回一下数据格式:

{"statusCode": 200,"successful": true,"message": null,"data": object
}

json对象中data是返回的实际结果对象,可以是一个对象、一个list、一个字符串、一个数字......

但是整体的json格式要以上面的为准

一般这种情况我们有两种实现方式:

1、自定义一个统一返回类

2、使用过滤器(Filter)实现

下面先介绍第一种,自定义一个接口返回类:

创建对应的接口类和实现类

  • ApiResponse.cs//实现类
  • IApiResponse.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; }}

保证了所有相关对象都来自 IApiResponse 接口

ApiResponse.cs

    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};}}

分别实现类带有泛型的 ApiResponse<T> 类和 ApiResponse 类 

注意在泛型类中,使用运算符重载,实现了 ApiResponse 到 ApiResponse<T> 的隐式转换。

在接口实现处返回一个 ApiResponse<T> 对象:

        [HttpGet]public ApiResponse<UserEntity> Get(string name){var list = new List<UserEntity>() {new UserEntity() { Name = "张三" },new UserEntity(){Name = "李四"}};var user = list.Find(p => p.Name == name);return user == null ? ApiResponse.NotFound() : new ApiResponse<UserEntity>(user);}

注意看最后一句 

return user == null ? ApiResponse.NotFound() : new ApiResponse<UserEntity>(user);

ApiResponse.NotFound() 返回的是一个 ApiResponse 对象

但这接口的返回值明明是 ApiResponse<UserEntity> 类型呀,这不是类型不一致吗?

不过在 ApiResponse<T> 中,我们定义了一个运算符重载,实现了 ApiResponse 类型到 ApiResponse<T> 的隐式转换,所以就完美解决这个问题,大大减少了代码量。

来看一下最后运行效果:

下一章介绍一下如何通过自定义过滤器的方式实现统一接口返回数据格式:

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

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

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

相关文章

智能图像编辑软件Luminar Neo mac提供多种调整和滤镜选项

Luminar Neo mac是一款由Skylum公司开发的AI技术图像编辑软件&#xff0c;旨在为摄影师和视觉艺术家提供创意图像编辑解决方案。Luminar Neo拥有强大的AI技术和丰富的后期处理工具&#xff0c;可帮助用户快速轻松地实现从基本到高级的图像编辑需求。 Luminar Neo提供了多种调整…

同步与互斥(二)

一、谁上锁就由谁解锁&#xff1f; 互斥量、互斥锁&#xff0c;本来的概念确实是&#xff1a;谁上锁就得由谁解锁。 但是FreeRTOS并没有实现这点&#xff0c;只是要求程序员按照这样的惯例写代码。 main函数创建了2个任务&#xff1a; 任务1&#xff1…

先进制造身份治理现状洞察:从手动运维迈向自动化身份治理时代

在新一轮科技革命和产业变革的推动下&#xff0c;制造业正面临绿色化、智能化、服务化和定制化发展趋势。为顺应新技术革命及工业发展模式变化趋势&#xff0c;传统工业化理论需要进行修正和创新。其中&#xff0c;对工业化水平的判断标准从以三次产业比重标准为主回归到工业技…

Kubernetes 容器编排(7)

离线业务编排详解 在线业务和离线业务 在线业务 Deployment、StatefulSet以及 DaemonSet 这三个编排概念的共同之处是&#xff1a;它们主要编排的对象&#xff0c;都是"在线业务"&#xff0c;即&#xff1a;Long Running Task&#xff08;长作业&#xff09;。比如…

尚硅谷 java 2023(基础语法)笔记

一、变量与运算符 1、HelloWorld的编写和执行 class HelloChina{public static void main(String[] args){System.out.println("hello,world!!你好&#xff0c;中国&#xff01;");} } 总结&#xff1a; 1. Java程序编写和执行的过程&#xff1a; 步骤1&#xff1…

HackTheBox - Medium - Linux - Sandworm (我的创作纪念日

Sandworm Sandworm 是一台中等难度的 Linux 机器&#xff0c;它托管了一个具有“PGP”验证服务的 Web 应用程序&#xff0c;该服务容易受到服务器端模板注入 &#xff08;SSTI&#xff09; 的攻击&#xff0c;导致“Firejail”监狱内的远程代码执行 &#xff08;RCE&#xff0…

12、Qt:用QProcess类启动外部程序:简单使用

一、说明 简单使用&#xff1a;在一个函数中&#xff0c;使用QProcess类的临时对象调用可执行文件exe&#xff0c;只有这个exe执行完了&#xff0c;这个函数才往下执行&#xff0c;一次性打印出exe所有输出信息&#xff1b;复杂使用&#xff1a;创建QProcess类的全局对象&…

STM32F4的DHT11初始化与实例分析

STM32—— DHT11 本文主要涉及STM32F4 的DHT11的使用以及相关时序的介绍&#xff0c;最后有工程下载地址。 文章目录 STM32—— DHT11一、 DHT11的介绍1.1 DHT11的经典电路 二、DHT11的通信2.1 DHT11的传输数据格式2.2 DHT11 通信分步解析 三、 DHT11 代码3.1 引脚图3.2 电路图…

阿里云林立翔:基于阿里云 GPU 的 AIGC 小规模训练优化方案

云布道师 本篇文章围绕生成式 AI 技术栈、生成式 AI 微调训练和性能分析、ECS GPU 实例为生成式 AI 提供算力保障、应用场景案例等相关话题展开。 生成式 AI 技术栈介绍 1、生成式 AI 爆发的历程 在 2022 年的下半年&#xff0c;业界迎来了生成式 AI 的全面爆发&#xff0c…

【接口测试】HTTP接口详细验证清单

概述 当我们在构建、测试、发布一套新的HTTP API时&#xff0c;包括我在内的大多数人都不知道他们所构建的每一个组件的复杂性和细微差别。 即使你对每一个组件都有深刻的理解&#xff0c;也可能会有太多的信息在你的脑海中出现。 以至于我们不可能一下把所有的信息进行梳理…

pycharm下执行conda命令提示无法识别解决方案

1 问题描述 win10环境命令行执行conda命令&#xff0c;报命令无法识别&#xff0c;错误信息如下&#xff1a; PS D:\code\cv> conda activate pt conda : 无法将“conda”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;如果包括路径&a…

python基础语法总结

基础是深入必不可少的&#xff0c;如果没有基础的支持&#xff0c;后面都是浮云&#xff0c;就像情侣之间&#xff0c;没有感情基础是不会有好结果的&#xff0c;物资基础是靠两个人打拼的&#xff0c;所以学习就像谈恋爱&#xff0c;两个人要学会沟通&#xff0c;才能修成正果…

循环神经网络中的梯度消失或梯度爆炸问题产生原因分析(二)

上一篇中讨论了一般性的原则&#xff0c;这里我们具体讨论通过时间反向传播&#xff08;backpropagation through time&#xff0c;BPTT&#xff09;的细节。我们将展示目标函数对于所有模型参数的梯度计算方法。 出于简单的目的&#xff0c;我们以一个没有偏置参数的循环神经…

在Linux环境下模拟实现命令解释器用c语言实现mypwd「粉丝答疑」

粉丝提问 Solution 要在 Linux 环境下用 C 语言模拟实现一个命令解释器&#xff0c;包含mypwd, mymkdir, myrmdir, mycd, mylist, mycp, mydate, mycreate, mydelete, exit等基本命令&#xff0c;需要按照以下步骤进行&#xff1a; 理解每个命令的功能&#xff1a; mypwd: 显示…

SQL---Zeppeline前驱记录与后驱记录查询

内容导航 类别内容导航机器学习机器学习算法应用场景与评价指标机器学习算法—分类机器学习算法—回归机器学习算法—聚类机器学习算法—异常检测机器学习算法—时间序列数据可视化数据可视化—折线图数据可视化—箱线图数据可视化—柱状图数据可视化—饼图、环形图、雷达图统…

RTP/RTCP/RTSP/SIP/SDP/RTMP对比

RTP&#xff08;Real-time Transport Protocol&#xff09;是一种用于实时传输音频和视频数据的协议。它位于传输层和应用层之间&#xff0c;主要负责对媒体数据进行分包、传输和定时。 RTCP&#xff08;Real-Time Control Protocol&#xff09;是 RTP 的控制协议&#xff0c;…

TrustZone之可信操作系统

有许多可信内核&#xff0c;包括商业和开源的。一个例子是OP-TEE&#xff0c;最初由ST-Ericsson开发&#xff0c;但现在是由Linaro托管的开源项目。OP-TEE提供了一个功能齐全的可信执行环境&#xff0c;您可以在OP-TEE项目网站上找到详细的描述。 OP-TEE的结构如下图所示&…

Windows 系统彻底卸载 SQL Server 通用方法

Windows 系统彻底卸载 SQL Server 通用方法 无论什么时候&#xff0c;SQL Server 的安装和卸载都是一件让我们头疼的事情。因为不管是 SQL Server 还是 MySQL 的数据库&#xff0c;当我们在使用数据库时因为未知原因出现问题&#xff0c;想要卸载重装时&#xff0c;如果数据库…

vue element plus 管理系统路由菜单简要设计(后端获取菜单)

1 需求 管理系统“菜单”由后端接口返回&#xff0c;前端需要根据后端返回的“菜单”数组&#xff0c;构造路由&#xff0c;渲染侧栏菜单有些菜单是子菜单&#xff0c;有对应的路由&#xff0c;但是不在侧栏显示&#xff08;比如一些详情页面&#xff09; 注&#xff1a;这里的…

Asp.Net Core 项目中常见中间件调用顺序

常用的 AspNetCore 项目中间件有这些&#xff0c;调用顺序如下图所示&#xff1a; 最后的 Endpoint 就是最终生成响应的中间件。 Configure调用如下&#xff1a; public void Configure(IApplicationBuilder app, IWebHostEnvironment env){if (env.IsDevelopment()){app.UseD…