基於 abp vNext 和 .NET Core 開發博客項目 - 用AutoMapper搞定對象映射


系列文章

  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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM