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

news2025/2/6 12:53:40

在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.coloradmin.cn/o/1327919.html

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

相关文章

预警指挥中心建设方案

目录 1.系统概述 2.系统设计 一、设计原则 二、设计依据 3.建设内容 4.设备中心 4.1视频系统 4.2音频系统 4.2.1音响 4.2.2功放 4.2.3无线麦 4.2.4音频处理器 4.3控制系统 4.4视频会商系统 4.4.1全向麦 4.4.2高清摄像头 4.4.3会议终端 4.4.4系统软件 5.软件中…

COSP营造户外骑行新业态:2024深圳户外骑行展在深圳福田召开

随着人们生活水平的提高&#xff0c;绿色健康的生活方式备受关注&#xff0c;户外骑行作为一种绿色、健康的运动方式&#xff0c;越来越受到人们的青睐。此次展会将展示各种类型的户外骑行装备&#xff0c;包括自行车、头盔、手套、鞋类、骑行服等。深圳是中国户外骑行展会的重…

使用Flask逐步搭建Web应用程序

大家好&#xff0c;Flask是一个使用Python编写的轻量级Web应用框架。它被设计成简单、易于学习和使用的&#xff0c;同时具备足够的灵活性和扩展性&#xff0c;以满足各种规模的Web应用开发需求。本文我们将介绍一个使用Flask逐步搭建Web应用程序的简单入门示例。 1.安装Flask…

安装 PyCharm 2021.1 保姆级教程

作者&#xff1a;billy 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 前言 目前能下载到的最新版本是 PyCharm 2021.1。 请注意对应 Python 的版本&#xff1a; Python 2: 2.7Python 3: >3.6, <3.11…

HarmonyOS4.0系统性深入开发01应用模型的构成要素

应用模型的构成要素 应用模型是HarmonyOS为开发者提供的应用程序所需能力的抽象提炼&#xff0c;它提供了应用程序必备的组件和运行机制。有了应用模型&#xff0c;开发者可以基于一套统一的模型进行应用开发&#xff0c;使应用开发更简单、高效。 HarmonyOS应用模型的构成要…

flink使用sql-client-defaults.yml无效

希望在flink sql脚本启动时自动选择catalog&#xff0c;减少麻烦。于是乎配置sql-client-defaults.yaml&#xff1a; catalogs:- name: hive_catalogtype: icebergcatalog-type: hiveproperty-version: 1cache-enabled: trueuri: thrift://localhost:9083client: 5warehouse: …

什么是误差,什么是重构误差,误差与重构误差有什么区别?

重构误差 1.误差的概念2.重构误差的概念 1.误差的概念 在机器学习中&#xff0c;误差通常是指模型的输出与实际标签或者真实值之间的差异&#xff0c;通常用于评估模型的预测能力或者训练的优化过程。 2.重构误差的概念 重构误差是指通过学习到的模型来重新构建&#xff08;或…

案例135:基于微信小程序的房屋租赁管理系统的设计与实现

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

ArcGIS基础:便捷查看外业照片及识别举证照片方位角

打开工具&#xff1a;【地理标记照片转点】。 打开工具后&#xff0c;输入文件夹&#xff0c;并对相应的参数进行勾选。 右键&#xff0c;图层属性&#xff0c;打开【显示】&#xff0c;对【超链接】设置等参数进行勾选。 找到【符号系统】&#xff0c;点击【高级】&#xff…

关于外贸包裹的那些事

大早晨收到一个客户留言&#xff0c;询问能不能看一下他的货物包裹被送到了哪里&#xff0c;然后客户可以安排他的代理人联系去取包裹&#xff0c;我心里的第一感觉是难道包裹丢失了&#xff1f; 于是赶紧起来查看物流单号&#xff0c;单号显示早在半个多月前已经被他的国内代…

【数据结构】线段树算法总结(区间修改)

知识概览 线段树一般有5个操作&#xff1a; pushup&#xff1a;用子节点更新当前节点信息pushdown&#xff1a;把懒标记往下传build&#xff1a;初始化一棵树modify&#xff1a;修改一个区间query&#xff1a;查询一个区间 不带懒标记&#xff08;支持单点修改&#xff09;的线…

HarmonyOS构建第一个ArkTS应用(Stage模型)

构建第一个ArkTS应用&#xff08;Stage模型&#xff09; 创建ArkTS工程 若首次打开DevEco Studio&#xff0c;请点击Create Project创建工程。如果已经打开了一个工程&#xff0c;请在菜单栏选择File > New > Create Project来创建一个新工程。 选择Application应用开发…

从0开始学Git指令

从0开始学Git指令 因为网上的git文章优劣难评&#xff0c;大部分没有实操展示&#xff0c;所以打算自己从头整理一份完整的git实战教程&#xff0c;希望对大家能够起到帮助&#xff01; 初始化一个Git仓库&#xff0c;使用git init命令。 添加文件到Git仓库&#xff0c;分两步…

小红书kos和kop有什么区别,营销玩法有哪些

相信熟悉媒介传播的朋友&#xff0c;对于kol和koc都不陌生。但随着平台的发展和市场的进步&#xff0c;又出现了kos和kop。那么小红书kos和kop有什么区别&#xff0c;营销玩法有哪些&#xff1f; 一、什么是kos和kop KOS&#xff0c;全称叫做Key Opinion Sales&#xff0c;意思…

做外贸多想一步,多走一步

最近在网上给小儿买了一个液晶画画板&#xff0c;自从告诉小儿已经购物需要耐心等待之后&#xff0c;几乎每天小儿要询问几遍&#xff0c;快递到哪里了&#xff1f; 好不容易盼到了&#xff0c;结果打开一看却是个坏的&#xff0c;虽然外包装是好的&#xff0c;但是明显这个快…

编码器脉冲信号测量2路DI高速计数器PNP/NPN转RS-485数据采集模块 YL150-485 标准Modbus RTU协议

特点&#xff1a; ● 编码器解码转换成标准Modbus RTU协议 ● 可用作编码器计数器或者转速测量 ● 支持编码器计数&#xff0c;可识别正反转 ● 也可以设置作为2路独立DI高速计数器 ● 计数值支持断电自动保存 ● DI输入支持PNP和NPN输入 ● 继电器和机械开关输入时可以…

配置MUX VLAN示例(接入层设备)

一、组网需求 在企业网络中&#xff0c;企业所有员工都可以访问企业的服务器。但对于企业来说&#xff0c;希望企业内部部分员工之间可以互相交流&#xff0c;而部分员工之间是隔离的&#xff0c;不能够互相访问。为了解决上述问题&#xff0c;可在连接终端的交换机上部署MUX …

​​​​​​​配置MUX VLAN示例(接入层设备)

组网需求 在企业网络中&#xff0c;企业所有员工都可以访问企业的服务器。但对于企业来说&#xff0c;希望企业内部部分员工之间可以互相交流&#xff0c;而部分员工之间是隔离的&#xff0c;不能够互相访问。 如图1所示&#xff0c;为了解决上述问题&#xff0c;可在连接终端…

Android Studio 实现音乐播放器

目录 一、引言 视频效果展示&#xff1a; 1.启动页效果 2.登录页效果 3.注册页效果 4.歌曲列表页效果 5.播放页效果 二、详细设计 1.登陆注册功能 2.音乐列表页面 2.音乐播放功能 三、源码获取 一、引言 Android初学者开发第一个完整的实例项目应该就属《音乐播放器…

keil 5 : Error: L6218E: Undefined symbol 问题解决方法小记

1.路径已添加但依旧包找不到定义的错误,这里找不到的是DFP包中的函数 2.点击Manage Run-Time Environment->打开Device->ATC Driver->勾选SPI&#xff08;找到你未定义函数所在的DFP包中的模块&#xff09; 3.编译后&#xff0c;点击Open definition会成功跳转到函数…