前面写了很多有关OData使用的文章,很多读者会有疑问,直接将实体对象暴露给最终用户会不会有风险?$expand在默认配置的情况下,数据会不会有泄露风险?

答案是肯定的,由于OData的特性,提供给我们便捷同时也会带来一些风险。很多地方推荐使用DTO模式来隔离实体类与最终用户使用到类的关系,从而解决以上两个问题,OData同样也适用。

DTO

DTO代表Data Transfer Object,是一种设计模式,用于在不同层之间传输数据。它通常用于将数据从一个应用程序的逻辑层传输到另一个应用程序的界面层或持久化层,以及在分布式系统中传输数据。

DTO对象是纯数据对象,它包含要从一个应用程序传输到另一个应用程序的数据。它不包含业务逻辑或数据访问代码,因此它们不能直接与数据库交互或执行任何操作,而只是简单地保存数据。

DTO对象通常由开发人员创建,并且可以根据需要进行扩展。它们可以包含各种属性和方法,以提供使用方便和更好的可读性。使用DTO对象可以降低耦合度,使不同层之间的数据传输更加简单和安全。

AutoMapper

我们需要将实体对象与DTO进行转换,对于需要转换数量不是很多的情况,直接编写一个转换函数就方便了。

    public static class DeviceDataExtension
{
public static DeviceDataDto ToDeviceDataDto(this Datum deviceData)
{
if (deviceData == null) return null;
DeviceDataDto deviceDataDto = new()
{
DataArray = deviceData.DataArray,
DeviceId = deviceData.DeviceId,
Timestamp = deviceData.Timestamp,
Id = Guid.NewGuid().ToString()
};
return deviceDataDto;
}
}

但是如果需要映射的属性很多,或者有很多对象的情况,建议使用对象映射工具:AutoMapper。基础用法不详细说了,讲讲对OData的支持。

首先安装对OData支持的包,由于我使用默认的DI,还需要安装DI支持的包:

Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection
Install-Package AutoMapper.AspNetCore.OData.EFCore

然后有三个要求:

  • 一定要对对象声明显示展开(explicit expansion)。
  • 调用IMapper的GetAsync()或者GetQueryAsync()方法。
  • 不能在Controller或者方法上使用[EnableQuery]特性:这个我熟,因为GetQueryAsync()函数需要利用ODataQueryOptions参数,如果同时使用[EnableQuery]会导致对结果再进行一次筛选,导致返回数据错误。

代码:

            services.AddAutoMapper(option =>
{
option.CreateMap<Datum, DeviceDataDto>()
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => Guid.NewGuid().ToString()))
.ForPath(dest => dest.DataArray, opt => opt.MapFrom(src => src.DataArray))
.ForAllMembers(w => w.ExplicitExpansion());
});
        public DeviceDatasController(IMapper mapper)
{
_mapper = mapper;
} [HttpGet]
[ProducesResponseType(typeof(IEnumerable<DeviceDataDto>), Status200OK)]
public async Task<IActionResult> GetAsync(string key, ODataQueryOptions<DeviceDataDto> options)
{
var insp = await _context.DeviceData.Where(w => w.DeviceId == key).GetQueryAsync(_mapper, options);
return Ok(insp);
}

这样,我们就可以正常使用 OData,同时也享受了的 DTO 的好处,即可以对 DeviceDataDto 使用的 OData 查询。使用的时候要注意,如果有导航属性,导航属性也需要配置映射。

参考资料

武装你的WEBAPI-OData与DTO的更多相关文章

  1. OData – the best way to REST–实例讲解ASP.NET WebAPI OData (V4) Service & Client

    一.概念介绍 1.1,什么是OData? 还是看OData官网的简单说明: An open protocol to allow the creation and consumption of quer ...

  2. AspNet WebApi OData 学习

    OData介绍:是一个查询和更新数据的Web协议.OData应用了web技术如HTTP.Atom发布协议(AtomPub)和JSON等来提供对不同应用程序,服务 和存储的信息访问.除了提供一些基本的操 ...

  3. AspNet.WebAPI.OData.ODataPQ

    AspNet.WebAPI.OData.ODataPQ实现WebAPI的分页查询服务 AspNet.WebAPI.OData.ODataPQ实现WebAPI的分页查询服务-(个人拙笔) AspNet. ...

  4. AspNet.WebAPI.OData.ODataPQ实现WebAPI的分页查询服务-(个人拙笔)

    AspNet.WebAPI.OData.ODataPQ 这是针对 Asp.net WebAPI OData 协议下,查询分页.或者是说 本人在使用Asp.Net webAPI 做服务接口时写的一个分页 ...

  5. 主攻ASP.NET MVC4.0之重生:Asp.Net MVC WebApi OData

    1.新建MVC项目,安装OData Install-Package Microsoft.AspNet.WebApi.OData -Version 4.0.0 2.新建WebAPI Controller ...

  6. AspNet.WebAPI.OData.ODataPQ实现WebAPI的分页查询服务-(个人拙笔)(转)

    出处:http://www.bubuko.com/infodetail-827612.html AspNet.WebAPI.OData.ODataPQ 这是针对 Asp.net WebAPI ODat ...

  7. [转]Composite Keys With WebApi OData

    本文转自:http://chris.eldredge.io/blog/2014/04/24/Composite-Keys/ In our basic configuration we told the ...

  8. [转]OData – the best way to REST–实例讲解ASP.NET WebAPI OData (V4) Service & Client

    本文转自:http://www.cnblogs.com/bluedoctor/p/4384659.html 一.概念介绍 1.1,什么是OData? 还是看OData官网的简单说明: An open ...

  9. webAPi OData的使用

    一.OData介绍 开放数据协议(Open Data Protocol,缩写OData)是一种描述如何创建和访问Restful服务的OASIS标准. 二.OData 在asp.net mvc中的用法 ...

  10. 基于Angular+WebAPI+OData的增删改查

    对于在ASP.NET WebAPI中怎么使用OData,已经在我前面的日志中的说明, 在ASP.NET Web API中使用OData 在这个示例中.我新建了一个Order的实体,在前端使用Angul ...

随机推荐

  1. 1.3Dmax界面_试图操作

    一.初始界面 1.菜单栏(软件的核心) 2.工具栏 3.石墨工具 4.命令板块 5.场景大纲 tools--> new Scene Explorer 创建的物体信息就会从出现在这里 6.视图窗口 ...

  2. WPF中的DataGrid支持Excell粘贴数据

    其中XMAL文件中的表格样式: <DataGrid x:Name="DataListView" AutoGenerateColumns="False" H ...

  3. pytest用例管理框架实战(基础篇)

    先安装pip install pytest pytest用例管理框架 默认规则: 1.py文件必须以test_开头或者_test结尾 2.类名必须以test开头 3.测试用例必须以test_开头 ge ...

  4. php 中 session存储

    转载网址: https://blog.csdn.net/miliu123456/article/details/107048378/ php 中 session 更换存储方式(file, redis, ...

  5. 一文读懂字符编码ASCII、Unicode与UTF-8

    先说一下,为什么写这篇文章? 最近在写一个Http协议栈当涉及CRLF控制字符写入时,发现自己对CRLF与\r\n的关系不太了解,因此决定详细学习一下:查阅资料的同时,又遇到UTF-8与ASCII编码 ...

  6. 三个经典的MySQL问题

    大家好,今天给大家上3个经典的MySQL问题,希望能对大家有帮助!但是因为笔者计算机水平有限,可能会存在一些错误,烦请指出.斧正!谢谢! 一.在MySQL中INNER JOIN.LEFT JOIN.R ...

  7. 在Vue3+TypeScript 前端项目中使用事件总线Mitt

    事件总线Mitt使用非常简单,本篇随笔介绍在Vue3+TypeScript 前端项目中使用的一些场景和思路.我们在Vue 的项目中,经常会通过emits 触发事件来通知组件或者页面进行相应的处理,不过 ...

  8. Kafka存储内幕详解

    1.概述 随着微服务和分布式计算的出现,Kafka已经成为各种主流平台系统架构中不可缺少的组成部分了.在本篇文章中,笔者将尝试为大家来解密Kafka的内部存储机制是如何运作的. 2.内容 在分布式系统 ...

  9. LabVIEW之同步——集合点vi

    这是一个对我来讲比较偏的工具,做过很多项目,没有用它也能完成各种各样的项目. 今天我们一起来了解下这个工具,所以称之为工具,因为它属于NI LabVIEW的白色节点,一般是有官方利用LabVIEW代码 ...

  10. pandas这dataframe结构

    认识DataFrame结构 DataFrame 一个表格型的数据结构,既有行标签(index),又有列标签(columns),它也被称异构数据表,所谓异构,指的是表格中每列的数据类型可以不同,比如可以 ...