使用ASP.NET Core 3.x 構建 RESTful API P11 P12 ActionResult of T 以及 AutoMapper

使用ASP.NET Core 3.x 構建 RESTful API P11 P12 ActionResult of T 以及 AutoMapper


博客園文章Id:12665843


IActionResult

實際上針對IActionResult接口有一個實現類,ActionResult<T> 所以一般當我們知道明確的返回類型時,我們也應該明確定義Action方法的返回值類型,示例代碼如下:


  /// <summary>
 /// 獲取所有公司信息
 /// </summary>
 [HttpGet]
 //public async Task<IActionResult> GetCompanies()
 public async Task<ActionResult<IEnumerable<CompanyDto>>> GetCompanies()
 {
     var companies = await this._companyRepository.GetCompaniesAsync();

     if (companies == null)
     {
         return NotFound();  // 404 NotFound  
     }

     //return Ok(companies);

     var companyDtos = new List<CompanyDto>();

     foreach (var item in companies)
     {
         companyDtos.Add(new CompanyDto
         {
             Id = item.Id,
             Name = item.Name
         });
     }

     return Ok(companyDtos);
 }

這樣做的好處是,我們可以將返回的資源,具體的類型明確化,它的好處體現在,比如當我們使用Swagger插件來生成接口文檔時,就可以明確的知道返回值類型了.

以上面代碼爲例,接口方法返回的結果類型實際上可以有以下幾種形式:

  1. 當申明的返回值類型爲: Task<ActionResult<IEnumerable<CompanyDto>>> 那麼返回值類型可以寫成return companyDtos,也可以寫成 return Ok(companyDtos);

  2. 當聲明的返回值類型爲: 在Task中直接是返回值類型 如: Task<IEnumerable<CompanyDto>> 那麼返回值類型就應該返回具體的類型 return companyDtos ;

  3. 當聲明的返回值類型爲: 在Task中的類型爲 IActionResult 那麼具體的返回值,可以寫成 return Ok(companyDtos) 這種形式.

綜上所述,我們應該儘可能的使用第一種寫法.

對象映射器 AutoMapper

在 .Net 的生態中,AutoMapper 是比較豐富的對象映射器,它提供了豐富的配置方法,方便開發者對兩個對象之間配置映射關係.

  1. 首先我們需要先通過Nuget來安裝AutoMapper的依賴項.

通過NuGet安裝 AutoMapper依賴
通過NuGet安裝 AutoMapper依賴

AutoMapper.Extensions.Microsoft.DependencyInjection可以更好的和 .Net Core的管道進行結合.

A convention-based object-object mapper基於約定的對象到對象的映射器

  1. 然後我們需要在 .Net Core容器配置的方法中,註冊AutoMapper服務.

  /*
   * 在容器配置方法中,添加AutoMapper服務,
   * 參數的意義上,在指定程序集中掃描 AutoMapper 的配置文件.
   */
services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
  1. 在項目下添加Profiles文件夾,此文件夾中用於裝載AutoMapper映射關係的配置.

配置代碼:

using AutoMapper;
using Routine.Api.Entitle;
using Routine.Api.Models;

namespace Routine.Api.Profiles
{
    public class CompanyProfile : Profile
    {
        /// <summary>
        /// 需要在構造函數中配置映射關係
        /// </summary>
        public CompanyProfile()
        {
            /*
             * 創建從Company(原對象),到CompanyDto(目標對象)的映射
             */
            CreateMap<Company, CompanyDto>()
                .ForMember(
                    dest=>dest.CompanyName,//目標屬性
                    opt=>opt.MapFrom(src=>src.Name) //表示配置目標屬性的映射源  即從Company中的name映射到CompanyDto中的CompanyName
                    );
        }
    }
}

AutoMapper的一些要點:

  • AutoMapper是基於約定的,如果原對象,和目標對象中的屬性名稱是相同的,那麼AutoMapper會自動進行映射.
  • 如果目標類型的某個屬性在源類型中沒有,那麼就會自動會被忽略,不會被賦值,即爲null.
  • 針對自動映射沒有辦法成功的屬性,AutoMapper會提供一系列可以配置的方法,用於指定屬性間的映射關係.
  1. 使用AutoMapper 來組織映射,如果要使用AutoMapper來組織映射,我們需要在控制器的構造函數中,配置注入.
private readonly ICompanyRepository _companyRepository;
private readonly IMapper _mapper;

public CompaniesController(ICompanyRepository companyRepository,IMapper mapper)
 {
            _companyRepository = companyRepository ?? throw new ArgumentNullException(nameof(companyRepository));
            _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
}
  1. 使用AutoMapper的代碼如下:
/// <summary>
/// 獲取所有公司信息
/// </summary>
[HttpGet]
//public async Task<IActionResult> GetCompanies()
public async Task<ActionResult<IEnumerable<CompanyDto>>> GetCompanies()
{
    var companies = await this._companyRepository.GetCompaniesAsync();

    if (companies == null)
    {
        return NotFound();  // 404 NotFound  
    }

    //return Ok(companies);



    //自己指定映射關係
    //var companyDtos = new List<CompanyDto>();
    //foreach (var item in companies)
    //{
    //    companyDtos.Add(new CompanyDto
    //    {
    //        Id = item.Id,
    //        CompanyName = item.Name
    //    });
    //}
    //return Ok(companyDtos);

    //使用AutoMapper的映射關係

    //T是目標類型, 參數中是源類型
    var result = this._mapper.Map<IEnumerable<CompanyDto>>(companies);

    return Ok(result);
 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章