基于 abp vNext 和 .NET Core 开发博客项目 - 用AutoMapper搞定对象映射

1|0系列文章

  1. 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目
  2. 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来
  3. 基于 abp vNext 和 .NET Core 开发博客项目 - 完善与美化,Swagger登场
  4. 基于 abp vNext 和 .NET Core 开发博客项目 - 数据访问和代码优先
  5. 基于 abp vNext 和 .NET Core 开发博客项目 - 自定义仓储之增删改查
  6. 基于 abp vNext 和 .NET Core 开发博客项目 - 统一规范API,包装返回模型
  7. 基于 abp vNext 和 .NET Core 开发博客项目 - 再说Swagger,分组、描述、小绿锁
  8. 基于 abp vNext 和 .NET Core 开发博客项目 - 接入GitHub,用JWT保护你的API
  9. 基于 abp vNext 和 .NET Core 开发博客项目 - 异常处理和日志记录
  10. 基于 abp vNext 和 .NET Core 开发博客项目 - 使用Redis缓存数据
  11. 基于 abp vNext 和 .NET Core 开发博客项目 - 集成Hangfire实现定时任务处理
  12. 基于 abp vNext 和 .NET Core 开发博客项目 - 用AutoMapper搞定对象映射
  13. 基于 abp vNext 和 .NET Core 开发博客项目 - 定时任务最佳实战(一)
  14. 基于 abp vNext 和 .NET Core 开发博客项目 - 定时任务最佳实战(二)
  15. 基于 abp vNext 和 .NET Core 开发博客项目 - 定时任务最佳实战(三)
  16. 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(一)
  17. 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(二)
  18. 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(三)
  19. 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(四)
  20. 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(五)
  21. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(一)
  22. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(二)
  23. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(三)
  24. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(四)
  25. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(五)
  26. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(六)
  27. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(七)
  28. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(八)
  29. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(九)
  30. 基于 abp vNext 和 .NET Core 开发博客项目 - 终结篇之发布项目

上一篇文章(https://www.cnblogs.com/meowv/p/12961014.html)集成了定时任务处理框架Hangfire,完成了一个简单的定时任务处理解决方案。

本篇紧接着来玩一下AutoMapper,AutoMapper可以很方便的搞定我们对象到对象之间的映射关系处理,同时abp也帮我们是现实了IObjectMapper接口,先根据官方文档:https://docs.abp.io/zh-Hans/abp/latest/Object-To-Object-Mapping ,将AutoMapper添加依赖到项目中。

.Application层模块类中添加AbpAutoMapperModule模块依赖。

//MeowvBlogApplicationModule.cs using Meowv.Blog.Application.Caching; using Volo.Abp.AutoMapper; using Volo.Abp.Identity; using Volo.Abp.Modularity; namespace Meowv.Blog.Application { [DependsOn( typeof(AbpIdentityApplicationModule), typeof(AbpAutoMapperModule), typeof(MeowvBlogApplicationCachingModule) )] public class MeowvBlogApplicationModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { ... } } }

在本项目中,主要处理的就是实体和DTO之前的映射关系,以之前写的BlogService.cs中的增删改查为例,将Post.csPostDto.cs互相映射。

先看GetPostAsync(int id)这个方法,之前的做法是手动创建对象,然后为其一个一个的赋值,可以想象当我们的字段超级多的时候,都得写一遍。现在有了AutoMapper,一句代码就可以搞定。

public async Task<ServiceResult<PostDto>> GetPostAsync(int id) { var result = new ServiceResult<PostDto>(); var post = await _postRepository.GetAsync(id); if (post == null) { result.IsFailed("文章不存在"); return result; } //var dto = new PostDto //{ // Title = post.Title, // Author = post.Author, // Url = post.Url, // Html = post.Html, // Markdown = post.Markdown, // CategoryId = post.CategoryId, // CreationTime = post.CreationTime //}; var dto = ObjectMapper.Map<Post, PostDto>(post); result.IsSuccess(dto); return result; }

ObjectMapperApplicationService中已经被注入,我们的继承了ServiceBase,可以直接使用。

到这里还没完,其中最重要的一步就是定义类与类之间的映射关系,AutoMapper提供了多种定义类之间映射的方法,有关详细信息请参阅AutoMapper的文档:https://docs.automapper.org/

其中定义一种映射的方法是创建一个Profile 类,在.Application层添加MeowvBlogAutoMapperProfile.cs,直接继承Profile在构造函数中定义即可。

//MeowvBlogAutoMapperProfile.cs using AutoMapper; using Meowv.Blog.Application.Contracts.Blog; using Meowv.Blog.Domain.Blog; namespace Meowv.Blog.Application { public class MeowvBlogAutoMapperProfile : Profile { public MeowvBlogAutoMapperProfile() { CreateMap<Post, PostDto>(); CreateMap<PostDto, Post>().ForMember(x => x.Id, opt => opt.Ignore()); } } }

定义两个规则,第一个:从Post映射到PostDto,因为PostDto所有属性在Post中都是存在的,所以直接CreateMap<>即可;第二个:从PostDto映射到Post,因为Post中存在Id属性,而在PostDto中是没有的,所以可以使用ForMember(...)来忽略掉Id属性。

定义好映射规则后,在模块类中添加使用。

//MeowvBlogApplicationModule.cs ... public override void ConfigureServices(ServiceConfigurationContext context) { Configure<AbpAutoMapperOptions>(options => { options.AddMaps<MeowvBlogApplicationModule>(validate: true); options.AddProfile<MeowvBlogAutoMapperProfile>(validate: true); }); } ...

使用同样的方式修改一下InsertPostAsync(PostDto dto)方法的代码。

public async Task<ServiceResult<string>> InsertPostAsync(PostDto dto) { var result = new ServiceResult<string>(); //var entity = new Post //{ // Title = dto.Title, // Author = dto.Author, // Url = dto.Url, // Html = dto.Html, // Markdown = dto.Markdown, // CategoryId = dto.CategoryId, // CreationTime = dto.CreationTime //}; var entity = ObjectMapper.Map<PostDto, Post>(dto); var post = await _postRepository.InsertAsync(entity); if (post == null) { result.IsFailed("添加失败"); return result; } result.IsSuccess("添加成功"); return result; }

解放了双手,代码也变少了,真香,去测试一下用了对象映射后的接口是否好使。

0

可以看到,结果也是可以出来的,后续都将按照上面的方法大量用到对象映射。

顺便介绍.HttpApi.Hosting层几个配置属性。

路由规则配置,默认Swagger中的路由是大写的,如果我想转成小写可以使用以下配置代码,都写在模块类MeowvBlogHttpApiHostingModule.cs中。

public override void ConfigureServices(ServiceConfigurationContext context) { ... context.Services.AddRouting(options => { // 设置URL为小写 options.LowercaseUrls = true; // 在生成的URL后面添加斜杠 options.AppendTrailingSlash = true; }); ... }

使用HSTS的中间件,该中间件添加了严格传输安全头。

public override void OnApplicationInitialization(ApplicationInitializationContext context) { ... app.UseHsts(); ... }

直接使用默认的跨域配置。

public override void OnApplicationInitialization(ApplicationInitializationContext context) { ... app.UseCors(); ... }

HTTP请求转HTTPS。

public override void OnApplicationInitialization(ApplicationInitializationContext context) { ... app.UseHttpsRedirection(); ... }

转发将标头代理到当前请求,配合 Nginx 使用,获取用户真实IP。

public override void OnApplicationInitialization(ApplicationInitializationContext context) { ... pp.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto }); ... }

本篇介绍了如何使用AutoMapper,搞定对象到对象间的映射,篇幅简短,内容比较简单,你学会了吗?😁😁😁

开源地址:https://github.com/Meowv/Blog/tree/blog_tutorial


__EOF__

本文作者阿星Plus
本文链接https://www.cnblogs.com/meowv/p/12966092.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   阿星Plus  阅读(2286)  评论(4编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示