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

.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博客

相关文章:

  • 【WebRTC---源码篇】(二十五)音视频同步
  • C++之深拷贝和浅拷贝
  • 测试理论知识四:大型软件的测试技巧——单元测试
  • DotNet Core 在Centos上使用环境变量运行 urls 参数
  • 《每天一分钟学习C语言·七》指针、字节对齐等
  • 只更新软件,座椅为何能获得加热功能?——一文读懂OTA
  • npm的使用技巧
  • UE5 Landscape 制作GIS卫星图地形
  • docker的应用和定义
  • [CVPR 2023:3D Gaussian Splatting:实时的神经场渲染]
  • RTP/RTCP/RTSP/SIP/SDP/RTMP对比
  • 10 Vue3中v-html指令的用法
  • 【Matlab in VSCode】在VSCode中编辑MATLAB文件
  • Win7如何修改MAC地址
  • 油猴脚本教程案例【键盘监听】-编写 ChatGPT 快捷键优化
  • Android系统模拟器绘制实现概述
  • Git学习与使用心得(1)—— 初始化
  • gops —— Go 程序诊断分析工具
  • input的行数自动增减
  • Java 11 发布计划来了,已确定 3个 新特性!!
  • Java Agent 学习笔记
  • laravel 用artisan创建自己的模板
  • overflow: hidden IE7无效
  • spring boot 整合mybatis 无法输出sql的问题
  • 极限编程 (Extreme Programming) - 发布计划 (Release Planning)
  • 温故知新之javascript面向对象
  • 白色的风信子
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • #stm32整理(一)flash读写
  • (2)MFC+openGL单文档框架glFrame
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • ****** 二 ******、软设笔记【数据结构】-KMP算法、树、二叉树
  • *p++,*(p++),*++p,(*p)++区别?
  • .mysql secret在哪_MYSQL基本操作(上)
  • .net 7 上传文件踩坑
  • .NET CF命令行调试器MDbg入门(四) Attaching to Processes
  • .Net IE10 _doPostBack 未定义
  • .net wcf memory gates checking failed
  • .NET 设计模式初探
  • .NET/C# 使窗口永不获得焦点
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题
  • .Net多线程总结
  • @31省区市高考时间表来了,祝考试成功
  • @LoadBalanced 和 @RefreshScope 同时使用,负载均衡失效分析
  • @PreAuthorize注解
  • [<事务专题>]
  • [AIGC] 开源流程引擎哪个好,如何选型?
  • [Android] Implementation vs API dependency
  • [BUUCTF 2018]Online Tool
  • [FUNC]判断窗口在哪一个屏幕上
  • [leetcode] 四数之和 M
  • [Lucene] Lucene 全文检索引擎简介
  • [Luogu 3958] NOIP2017 D2T1 奶酪
  • [na]wireshark抓包排错-tcp.flags.reset