OData WebAPI实践-兼容OData集合响应
本文属于 OData 系列文章
引言
OData 是一个开放标准,已经在 oasis 组织标准化,因此我们可以在标准的官网查询到 OData 的标准请求与返回形式:OData JSON Format Version 4.01 (oasis-open.org)
针对不同的数据类型,输出返回的格式也不尽相同,涉及的内容非常多。日常使用 OData 的过程中,我们经常处理的是实体对象以及实体对象的集合。如果直接返回 IQueryable
用于 OData 查询,那么返回的数据大多是集合(数组/列表)。
{
"@odata.context": "http://localhost:9000/api/v2/$metadata#Collection(Datum_AggDto)",
"@odata.count": 2,
"value": [
{
"timestamp": 1682294400000,
"max": 180.0,
"min": 152.0,
"avg": 161.7605633802817
},
{
"timestamp": 1682985600000,
"max": 281.0,
"min": 180.0,
"avg": 228.39583333333334
}]
}
这个数组对象也不是很纯粹,它被 value 封装,并且提供了 @odata.context
元数据链接。如果我们的 API 没有被 OData 路由解析,那么默认 WEBAPI 会返回一个纯粹的数组对象:
[
{
"timestamp": 1682294400000,
"max": 180.0,
"min": 152.0,
"avg": 161.7605633802817
},
{
"timestamp": 1682985600000,
"max": 281.0,
"min": 180.0,
"avg": 228.39583333333334
}]
假设我们的对外的数据接口不完全被 OData 路由,会导致前端访问的行为不一致:一些 API 可以直接解析,另外一些 API 则需要使用 value 封装后处理。
封装非 OData Route Mapping
由于 OData 有了标准,为了对外保持一致性,我们可以尝试在返回非 OData 路由 API 时,将原始数组对象进行封装。
单实体对象
[HttpGet("/api/v1/Current")]
[ProducesResponseType(typeof(DeviceDataDto), Status200OK)]
public IActionResult Current(string key)
{
key = key.Trim('\'');
var data = _context.DeviceData.Where(w => w.DeviceId == key).OrderByDescending(w => w.Timestamp).FirstOrDefault();
return Ok(_mapper.Map<DeviceDataDto>(datas));
}
对于以上的代码,只返回单个实体对象,返回的形式与 OData 标准中返回单个实体对象的标准一致,因此不需要额外的转换操作。
{
//OData 返回会多一个context,普通API不会有。
"@odata.context": "http://localhost:9000/api/v2/$metadata#Datum_AggDto",
"timestamp": 1682985600000,
"max": 281.0,
"min": 180.0,
"avg": 228.39583333333334
}
实体对象集合
[HttpGet("/api/v1")]
[ProducesResponseType(typeof(IEnumerable<DeviceDataDto>), Status200OK)]
public async Task<IActionResult> Get(string key)
{
key = key.Trim('\'');
return Ok(await _context.DeviceData.Where(w => w.DeviceId == key).ToListAsync());
}
以上代码返回的类型是一个集合,并且被 OData 路由映射。我们使用 value 这个 key 对齐进行封装:
[HttpGet("/api/v1")]
[ProducesResponseType(typeof(IEnumerable<DeviceDataDto>), Status200OK)]
public async Task<IActionResult> Get(string key)
{
key = key.Trim('\'');
var datas = await _context.DeviceData.Where(w => w.DeviceId == key).ToListAsync();
var result = new { Value = datas };
return Ok(result);
}
注意这个 Value
我使用的是大写,由于我启用了 camelCase
,所以会自动转换为小写。这样前端访问 API 时,不论是否为 OData API 都可以访问 value 的值获取数组对象。
OData WebAPI实践-兼容OData集合响应的更多相关文章
- [转]OData/WebApi
本文转自:https://github.com/OData/WebApi/tree/vNext OData Web API Introduction OData Web API (i.e., ASP. ...
- [转]OData的初步认识 OData v4 Client Code Generator
本文转自:http://www.cnblogs.com/1zhk/p/5356053.html What – OData是什么? OData - Open Data Protocol,是一个设计和使用 ...
- .net core 杂记:WebAPI的XML请求和响应
一般情况下,restfult api 进行数据返回或模型绑定,默认json格式会比较常见和方便,当然偶尔也会需要以XML格式的要求 对于返回XML,普通常见的方式就是在每个aciton方法进行诸如X ...
- [整理]WebAPI中应用oData
http://www.odata.org/ http://bitoftech.net/category/odata/ http://www.hanselman.com/blog/CreatingAnO ...
- 快速搭建WebAPI(Odata+Code-First)附Odata条件查询表~
Odata是什么? 开放数据协议(Open Data Protocol,缩写OData)是一种描述如何创建和访问Restful服务的OASIS标准.该标准由微软发起,前三个版本1.0.2.0.3.0都 ...
- 写给新手的WebAPI实践
此篇是写给新手的Demo,用于参考和借鉴,用于发散思路.老鸟可以忽略了. 自己经常有这种情况,遇到一个新东西或难题,在了解和解决之前总是说“等搞定了一定要写篇文章记录下来”,但是当掌握了之后,就感觉好 ...
- Vue2.0 + Element-UI + WebAPI实践:简易个人记账系统
最近正在学习Vue2.0相关知识,正好近期饿了么桌面端组件Element-UI发布,便动手做了一款简易个人记账系统,以达到实践及巩固目的. 1.开发环境 Win10 + VS2015 + Sqlser ...
- webApi实践:开始WebApi 2
1.学习步骤总结 学习网址:http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-you ...
- [转]How to Use Web API OData to Build an OData V4 Service without Entity Framework
本文转自:http://www.odata.org/blog/how-to-use-web-api-odata-to-build-an-odata-v4-service-without-entity- ...
- videojs实践--兼容ie7,8
1,还是先上图 ie9+,ff,chrome,,,
随机推荐
- 【Apifox Helper】自动生成接口文档,IDEA+Apifox懒人必备
@ 目录 前言 缘由 接口文档对接爽,整理起来真费脑 ⏲️本文阅读时长 约10分钟 前置条件 1. IDEA开发工具 2. Apifox(不必要) 主要目标 一秒生成接口文档 水图 IDEA中项目接结 ...
- MybatisPlus------代码生成器
快速开发: 代码生成器: (1)模版:MyBatisPlus提供 (2)数据库相关配置:读取数据库获取信息 (3)开发者自定义配置:手工配置 package com.ithema; import co ...
- 《操作系统导论》读书笔记1——CPU虚拟化,进程
系列文章目录和关于我 一丶CPU的虚拟化 一个桃子,我们称之为物理(physical)桃子.但有很多想吃这个桃子的 人,我们希望向每个想吃的人提供一个属于他的桃子,这样才能皆大欢喜.我们把给每个 人的 ...
- SpringBoot 整合 Avro 与 Kafka
更多内容,前往IT-BLOG [需求]:生产者发送数据至 kafka 序列化使用 Avro,消费者通过 Avro 进行反序列化,并将数据通过 MyBatisPlus 存入数据库. 一.环境介绍 [1] ...
- TypeScript 学习笔记 — 基于对象操作的内置类型的使用(十二)
目录 1.Partial 转化可选属性 (?) 2.Required 转化必填属性 (-?) 3.Readonly 转化仅读属性 (readonly) Mutate(非内置,与 Readonly 相对 ...
- 细节拉满,80 张图带你一步一步推演 slab 内存池的设计与实现
1. 前文回顾 在之前的几篇内存管理系列文章中,笔者带大家从宏观角度完整地梳理了一遍 Linux 内存分配的整个链路,本文的主题依然是内存分配,这一次我们会从微观的角度来探秘一下 Linux 内核中用 ...
- 系统建模之UML用例视图
<用例视图> 1 用例图的目标 who「参与者」:确定谁要使用系统 what「功能」:他们使用系统做什么? 2 用例图-四大主要组件 2.1 参与者 参与者:与应用程序或系统进行交互的用户 ...
- 深入理解 python 虚拟机:字节码教程(2)——控制流是如何实现的?
深入理解 python 虚拟机:字节码教程(2)--控制流是如何实现的? 在本篇文章当中主要给大家分析 python 当中与控制流有关的字节码,通过对这部分字节码的了解,我们可以更加深入了解 pyth ...
- .NET周报 【4月第2期 2023-04-08】
国内文章 LRU缓存替换策略及C#实现 https://www.cnblogs.com/eventhorizon/p/17290125.html 这篇文章讲述了缓存替换策略,特别是LRU算法.LRU算 ...
- 从0到1手把手教你ASP.NET Core Web API项目配置接口文档Swagger(二)
传送门:从0到1手把手教你ASP.NET Core Web API项目配置接口文档Swagger(一) 一.设置Swagger页面为首页--开发环境 我们虽然可以在输入 /swagger 后顺利的访问 ...