Как использовать AutoMapper для отображения строки перечисления OData в запросе json dto на свойство перечисления объекта - PullRequest
0 голосов
/ 14 февраля 2020

Я работаю над новым ASP. NET Core 3.1.1 API с Microsoft.AspNetCore.OData v 7.3.0, AutoMapper v9.0.0 и Microsoft.AspNetCore. Mvc .Newtonsoft Json v3 .1.1

Я получаю следующую ошибку при выполнении процедуры POST для конечной точки учетных записей с использованием Postman v7.18.0;

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

Я рассмотрел аналогичный список вопросов при создании этого вопроса, но не смог найти решение. При просмотре в Google поисков по AutoMapper OData Enums все, что я мог найти, было рекомендацией украсить мой класс dto с помощью ...

[AutoMap(typeof(Account))]

... и украсить мои свойства dto enum с помощью ...

[JsonConverter(typeof(StringEnumConverter))]

Тем не менее, я все еще получаю ошибку. Я нашел ссылки на использование класса AutoMapperProfile с сопоставителем, определенным как

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

Но похоже, что AutoMapper v9.0.0 больше не имеет метода CreateMap. Насколько я понимаю, добавление [AutoMap (typeof (Account))] к классу dto имело тот же эффект, что и создание карты в классе профиля.

Я чувствую, что здесь я иду кругами так что я решил обратиться к SO-сообществу. Я уверен, что это что-то простое, я просто не вижу этого.

Вот мое тело POST-запроса от Почтальона;

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

Вот мой метод Post 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);

}

Вот класс моей учетной записи;

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; }
}

Вот класс моей учетной записи 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; }
}

А вот мои Enum для AccountTypes и StatusTypes

public enum AccountTypes
{
    Customer = 0,
    Reseller = 1,
    Provider = 2,
}

public enum StatusTypes
{
    Active = 0,
    Inactive = 1,
}

Есть идеи?

1 Ответ

0 голосов
/ 20 февраля 2020

Оказывается, мне нужно было создать экземпляр AutoMapper MapperConfiguration и назначить его мапперу.

Я закончил тем, что вставил в конструктор контроллера, например;

    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);
    }

После того, как я это сделал, все заработало как положено.

Вот ссылка на документы AutoMappers по теме.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...