武装你的WEBAPI-OData与DTO

本文属于OData系列文章

Intro

前面写了很多有关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 查询。使用的时候要注意,如果有导航属性,导航属性也需要配置映射。

参考资料

原文链接:https://www.cnblogs.com/podolski/archive/2023/05/08/17380728.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:武装你的WEBAPI-OData与DTO - Python技术站

(0)
上一篇 2023年5月8日
下一篇 2023年5月8日

相关文章

  • c#使用xamarin编写拨打电话程序

    很好,下面我来详细讲解一下“c#使用xamarin编写拨打电话程序”的完整攻略。 1. 环境搭建 首先,在开始编写程序前,需要先搭建好环境。我们可以在Visual Studio中使用Xamarin进行开发。在安装 Visual Studio 时选择安装移动开发选项以及Xamarin的组件,或者在已安装的Visual Studio中通过安装工具添加Xamari…

    C# 2023年6月3日
    00
  • C#不提升自己程序的权限实现操作注册表

    C#在windows下进行操作系统相关的功能时,通常需要提升程序的权限。这里介绍一种不必提升权限的方法,实现对Windows注册表的操作。 前置知识 这种方法需要使用到Windows API,具体是RegistryKey类中的API。在使用此方法前,你需要熟悉C#编程、Windows API以及注册表的相关知识。 实现方法 C#提供了RegistryKey类…

    C# 2023年5月15日
    00
  • c#中的interface abstract与virtual介绍

    针对“c#中的interface abstract与virtual介绍”的问题,我将会给出详细的解答。 一、介绍 在 C# 中,我们常常会用到 interface、abstract 和 virtual 这三个关键字。它们在面向对象的编程中,起到了非常重要的作用。 1.1 interface interface 是一种特殊的类,它只能包含成员的声明,而不提供任…

    C# 2023年5月31日
    00
  • C#窗体-数据库连接及登录功能的实现案例

    下面是“C#窗体-数据库连接及登录功能的实现案例”的攻略: 1. 案例需求 我们需要开发一个C#窗体应用程序,要求实现以下功能: 与数据库建立连接 用户登录功能,登录成功后跳转到主页面 用户登录失败,展示错误提示 2. 开发步骤 2.1 数据库连接 我们可以使用ADO.NET来实现与数据库的连接。首先需要在项目中添加数据库连接: 打开Visual Studi…

    C# 2023年6月1日
    00
  • C# WPF调用QT窗口的方法

    C# WPF调用QT窗口的方法 在开发中,有时我们需要使用C# WPF调用QT窗口,可以通过以下方法实现。 1. 安装QT开发工具并创建QT窗口 首先需要下载并安装QT开发工具,然后创建一个QT窗口,在窗口中添加需要的控件和逻辑代码,最后编译并生成QT窗口的可执行文件(exe文件)。 确保QT窗口的可执行文件能够正常运行,无误后进行下一步操作。 2. 编写C…

    C# 2023年6月7日
    00
  • C# 透明窗体制作实现方法比较分析

    C#中透明窗体的制作实现方法比较有不同的方式,本攻略将分别介绍三种用于制作透明窗体的方法,并分析比较它们的优缺点。 方式一:使用 Form 的 Opacity 属性 使用该方法,制作出的透明窗体是基于整个窗体的透明度来实现的,可使用 Form 的 Opacity 属性来设置窗体的透明程度,取值范围是0-1之间。 private void Form1_Load…

    C# 2023年6月6日
    00
  • C#的泛型方法解析

    针对C#的泛型方法解析,以下是一份完整攻略: 什么是泛型方法? 泛型方法是一种可以在运行时接受多种不同类型参数的方法,这样就避免了为每种类型都必须编写一个特定的方法的麻烦。泛型方法是使用泛型语法来定义的,例如: public T Add<T>(T a, T b) { return a + b; } 上面的例子中,我们定义了一个可以处理任何类型T的…

    C# 2023年5月15日
    00
  • C#简单爬虫案例分享

    下面我将为你详细讲解有关“C#简单爬虫案例分享”的完整攻略。 1. 爬虫原理 爬虫是指程序自动化地访问互联网资源并提取信息。其基本原理是通过HTTP请求,获取服务器返回的HTML页面,并解析其中的内容进行采集、处理和格式化。通常,爬虫程序的实现过程可以分为以下几个步骤: 发送HTTP请求,并获取服务器返回的HTML页面。 解析HTML页面中的内容,识别其中的…

    C# 2023年6月1日
    00
合作推广
合作推广
分享本页
返回顶部