如何使用 AutoMapper 将 json 请求 dto 中的 OData 枚举字符串映射到实体枚举属性

Posted

技术标签:

【中文标题】如何使用 AutoMapper 将 json 请求 dto 中的 OData 枚举字符串映射到实体枚举属性【英文标题】:How to use AutoMapper to map OData enum string in json request dto to entity enum property 【发布时间】:2020-05-30 11:46:02 【问题描述】:

我正在使用 Microsoft.AspNetCore.OData v 7.3.0、AutoMapper v9.0.0 和 Microsoft.AspNetCore.Mvc.NewtonsoftJson v3.1.1 开发新的 ASP.NET Core 3.1.1 API

当我使用 Postman v7.18.0 向 Accounts 端点发送 POST 时出现以下错误;

AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping.

我在创建此问题时查看了类似问题列表,但无法找到解决方案。 在审查 Google 搜索 AutoMapper OData Enums 时,我能找到的只是建议用...装饰我的 dto 类。

[AutoMap(typeof(Account))]

...并用...装饰我的 dto 枚举属性

[JsonConverter(typeof(StringEnumConverter))]

但是,我仍然收到错误消息。我找到了使用 AutoMapperProfile 类的引用,其映射器定义为

CreateMap<Account, AccountModel>().ReverseMap();

但 AutoMapper v9.0.0 似乎不再具有 CreateMap 方法。我的理解是,将 [AutoMap(typeof(Account))] 添加到 dto 类与在配置文件类中创建地图的效果相同。

我觉得我现在在这里绕圈子,所以我想联系 SO 社区。我确信这很简单,我只是没有看到它。

这是我来自 Postman 的 POST 请求正文;


  "@odata.context": "https://localhost:44367/v1/$metadata#Accounts",
  "AccountName": "Test Provider",
  "AccountType": "Provider",
  "IsTaxExempt": false,
  "Status": "Active"

这是我的 AccountsController Post 方法;

[ODataRoute]
[Produces("application/json;odata.metadata=minimal")]
[ProducesResponseType(typeof(AccountModel), Status201Created)]
[ProducesResponseType(Status400BadRequest)]
public async Task<IActionResult> Post([FromBody] AccountModel record)


    if (!ModelState.IsValid)
    
        return BadRequest(ModelState);
    
    record.Id = new Guid();
    var entity = _mapper.Map<Account>(record);
    _context.Add(entity);
    await _context.SaveChangesAsync();
    var createdRecord = _mapper.Map<AccountModel>(entity);
    return Created(createdRecord);


这是我的 Account 实体类;

public class Account : EntityBase

    [Required]
    [Column(TypeName = "nvarchar(50)")]
    [MaxLength(50)]
    public string AccountName  get; set; 

    public AccountTypes AccountType  get; set; 

    public bool IsTaxExempt  get; set; 


这里是EntityBase类;

public class EntityBase

    [Required]
    public Guid Id  get; set; 

    public DateTimeOffset? DateTimeCreated  get; set;  = DateTime.UtcNow;

    public DateTimeOffset? DateTimeLastModified  get; set; 

    [JsonConverter(typeof(StringEnumConverter))]
    public StatusTypes Status  get; set; 

    public bool DeleteFlag  get; set; 

这是我的 Account DTO 类;

[Filter, Count, Expand, OrderBy, Page, Select]
[AutoMap(typeof(Account))]
public class AccountModel : BaseModel

    [Required]
    [MaxLength(50)]
    public string AccountName  get; set; 

    [JsonConverter(typeof(StringEnumConverter))]
    public AccountTypes AccountType  get; set; 

    public bool IsTaxExempt  get; set; 

这是我的 BaseModel 类;

[Select, Filter]
public class BaseModel

    public Guid Id  get; set; 
    public DateTimeOffset DateTimeCreated  get; set;  = DateTime.UtcNow;
    public DateTimeOffset DateTimeLastModified  get; set; 

    [JsonConverter(typeof(StringEnumConverter))]
    public StatusTypes Status  get; set; 

    public bool DeleteFlag  get; set; 

这是我的 AccountTypes 和 StatusTypes 枚举

public enum AccountTypes

    Customer = 0,
    Reseller = 1,
    Provider = 2,


public enum StatusTypes

    Active = 0,
    Inactive = 1,

有什么想法吗?

【问题讨论】:

【参考方案1】:

事实证明,我需要创建一个 AutoMapper MapperConfiguration 的实例并将其分配给映射器。

例如,我最终放入了Controller的构造函数;

    public AccountsController(CdContext context, IMapper mapper)
     
        _context = context ?? throw new ArgumentNullException(nameof(context));
        _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
        var config = new MapperConfiguration(cfg => cfg.CreateMap<Account, AccountModel>().ReverseMap());
        _mapper = new Mapper(config);
    

在我这样做之后,一切都按预期进行。

Here is a link 发给 AutoMappers 的有关该主题的文档。

【讨论】:

docs.automapper.org/en/latest/…

以上是关于如何使用 AutoMapper 将 json 请求 dto 中的 OData 枚举字符串映射到实体枚举属性的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 AutoMapper 使用 EntityFramework 使用嵌套列表更新对象?

如何在 .NetCore 中使用 AutoMapper 高级功能

如何使用Automapper将更改映射到现有集合?

如何指定 automapper 异常导致的数据?

使用 AutoMapper 的 ProjectTo 和扩展选项时,每个请求都会增加内存

如何调试到 AutoMapper 代码?